| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 117 |
| 118 private: | 118 private: |
| 119 void PrintIndent() { | 119 void PrintIndent() { |
| 120 for (intptr_t i = 0; i < *indent_; i++) { | 120 for (intptr_t i = 0; i < *indent_; i++) { |
| 121 OS::Print(". "); | 121 OS::Print(". "); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 intptr_t* indent_; | 124 intptr_t* indent_; |
| 125 }; | 125 }; |
| 126 | 126 |
| 127 | |
| 128 #define TRACE_PARSER(s) \ | 127 #define TRACE_PARSER(s) \ |
| 129 TraceParser __p__(this->TokenPos(), this->script_, &this->trace_indent_, s) | 128 TraceParser __p__(this->TokenPos(), this->script_, &this->trace_indent_, s) |
| 130 | 129 |
| 131 #else // not DEBUG | 130 #else // not DEBUG |
| 132 #define TRACE_PARSER(s) | 131 #define TRACE_PARSER(s) |
| 133 #endif // DEBUG | 132 #endif // DEBUG |
| 134 | 133 |
| 135 | |
| 136 class BoolScope : public ValueObject { | 134 class BoolScope : public ValueObject { |
| 137 public: | 135 public: |
| 138 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { | 136 BoolScope(bool* addr, bool new_value) : _addr(addr), _saved_value(*addr) { |
| 139 *_addr = new_value; | 137 *_addr = new_value; |
| 140 } | 138 } |
| 141 ~BoolScope() { *_addr = _saved_value; } | 139 ~BoolScope() { *_addr = _saved_value; } |
| 142 | 140 |
| 143 private: | 141 private: |
| 144 bool* _addr; | 142 bool* _addr; |
| 145 bool _saved_value; | 143 bool _saved_value; |
| 146 }; | 144 }; |
| 147 | 145 |
| 148 | |
| 149 // Helper class to save and restore token position. | 146 // Helper class to save and restore token position. |
| 150 class Parser::TokenPosScope : public ValueObject { | 147 class Parser::TokenPosScope : public ValueObject { |
| 151 public: | 148 public: |
| 152 explicit TokenPosScope(Parser* p) : p_(p) { saved_pos_ = p_->TokenPos(); } | 149 explicit TokenPosScope(Parser* p) : p_(p) { saved_pos_ = p_->TokenPos(); } |
| 153 TokenPosScope(Parser* p, TokenPosition pos) : p_(p), saved_pos_(pos) {} | 150 TokenPosScope(Parser* p, TokenPosition pos) : p_(p), saved_pos_(pos) {} |
| 154 ~TokenPosScope() { p_->SetPosition(saved_pos_); } | 151 ~TokenPosScope() { p_->SetPosition(saved_pos_); } |
| 155 | 152 |
| 156 private: | 153 private: |
| 157 Parser* p_; | 154 Parser* p_; |
| 158 TokenPosition saved_pos_; | 155 TokenPosition saved_pos_; |
| 159 DISALLOW_COPY_AND_ASSIGN(TokenPosScope); | 156 DISALLOW_COPY_AND_ASSIGN(TokenPosScope); |
| 160 }; | 157 }; |
| 161 | 158 |
| 162 | |
| 163 class RecursionChecker : public ValueObject { | 159 class RecursionChecker : public ValueObject { |
| 164 public: | 160 public: |
| 165 explicit RecursionChecker(Parser* p) : parser_(p) { | 161 explicit RecursionChecker(Parser* p) : parser_(p) { |
| 166 parser_->recursion_counter_++; | 162 parser_->recursion_counter_++; |
| 167 // No need to check the stack unless the parser is in an unusually deep | 163 // No need to check the stack unless the parser is in an unusually deep |
| 168 // recurive state. Thus, we omit the more expensive stack checks in | 164 // recurive state. Thus, we omit the more expensive stack checks in |
| 169 // the common case. | 165 // the common case. |
| 170 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. | 166 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. |
| 171 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { | 167 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { |
| 172 parser_->CheckStack(); | 168 parser_->CheckStack(); |
| 173 } | 169 } |
| 174 } | 170 } |
| 175 ~RecursionChecker() { parser_->recursion_counter_--; } | 171 ~RecursionChecker() { parser_->recursion_counter_--; } |
| 176 | 172 |
| 177 private: | 173 private: |
| 178 Parser* parser_; | 174 Parser* parser_; |
| 179 }; | 175 }; |
| 180 | 176 |
| 181 | |
| 182 static RawTypeArguments* NewTypeArguments( | 177 static RawTypeArguments* NewTypeArguments( |
| 183 const GrowableArray<AbstractType*>& objs) { | 178 const GrowableArray<AbstractType*>& objs) { |
| 184 const TypeArguments& a = | 179 const TypeArguments& a = |
| 185 TypeArguments::Handle(TypeArguments::New(objs.length())); | 180 TypeArguments::Handle(TypeArguments::New(objs.length())); |
| 186 for (int i = 0; i < objs.length(); i++) { | 181 for (int i = 0; i < objs.length(); i++) { |
| 187 a.SetTypeAt(i, *objs.At(i)); | 182 a.SetTypeAt(i, *objs.At(i)); |
| 188 } | 183 } |
| 189 // Cannot canonicalize TypeArgument yet as its types may not have been | 184 // Cannot canonicalize TypeArgument yet as its types may not have been |
| 190 // finalized yet. | 185 // finalized yet. |
| 191 return a.raw(); | 186 return a.raw(); |
| 192 } | 187 } |
| 193 | 188 |
| 194 | |
| 195 void ParsedFunction::AddToGuardedFields(const Field* field) const { | 189 void ParsedFunction::AddToGuardedFields(const Field* field) const { |
| 196 if ((field->guarded_cid() == kDynamicCid) || | 190 if ((field->guarded_cid() == kDynamicCid) || |
| 197 (field->guarded_cid() == kIllegalCid)) { | 191 (field->guarded_cid() == kIllegalCid)) { |
| 198 return; | 192 return; |
| 199 } | 193 } |
| 200 | 194 |
| 201 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { | 195 for (intptr_t j = 0; j < guarded_fields_->length(); j++) { |
| 202 const Field* other = (*guarded_fields_)[j]; | 196 const Field* other = (*guarded_fields_)[j]; |
| 203 if (field->Original() == other->Original()) { | 197 if (field->Original() == other->Original()) { |
| 204 // Abort background compilation early if the guarded state of this field | 198 // Abort background compilation early if the guarded state of this field |
| (...skipping 11 matching lines...) Expand all Loading... |
| 216 } | 210 } |
| 217 | 211 |
| 218 // Note: the list of guarded fields must contain copies during background | 212 // Note: the list of guarded fields must contain copies during background |
| 219 // compilation because we will look at their guarded_cid when copying | 213 // compilation because we will look at their guarded_cid when copying |
| 220 // the array of guarded fields from callee into the caller during | 214 // the array of guarded fields from callee into the caller during |
| 221 // inlining. | 215 // inlining. |
| 222 ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread()); | 216 ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread()); |
| 223 guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw())); | 217 guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw())); |
| 224 } | 218 } |
| 225 | 219 |
| 226 | |
| 227 void ParsedFunction::Bailout(const char* origin, const char* reason) const { | 220 void ParsedFunction::Bailout(const char* origin, const char* reason) const { |
| 228 Report::MessageF(Report::kBailout, Script::Handle(function_.script()), | 221 Report::MessageF(Report::kBailout, Script::Handle(function_.script()), |
| 229 function_.token_pos(), Report::AtLocation, | 222 function_.token_pos(), Report::AtLocation, |
| 230 "%s Bailout in %s: %s", origin, | 223 "%s Bailout in %s: %s", origin, |
| 231 String::Handle(function_.name()).ToCString(), reason); | 224 String::Handle(function_.name()).ToCString(), reason); |
| 232 UNREACHABLE(); | 225 UNREACHABLE(); |
| 233 } | 226 } |
| 234 | 227 |
| 235 | |
| 236 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { | 228 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { |
| 237 if (kernel_scopes_ == NULL) { | 229 if (kernel_scopes_ == NULL) { |
| 238 intptr_t kernel_offset = function().kernel_offset(); | 230 intptr_t kernel_offset = function().kernel_offset(); |
| 239 Script& script = Script::Handle(Z, function().script()); | 231 Script& script = Script::Handle(Z, function().script()); |
| 240 kernel::StreamingScopeBuilder builder( | 232 kernel::StreamingScopeBuilder builder( |
| 241 this, kernel_offset, script.kernel_data(), script.kernel_data_size()); | 233 this, kernel_offset, script.kernel_data(), script.kernel_data_size()); |
| 242 kernel_scopes_ = builder.BuildScopes(); | 234 kernel_scopes_ = builder.BuildScopes(); |
| 243 } | 235 } |
| 244 return kernel_scopes_; | 236 return kernel_scopes_; |
| 245 } | 237 } |
| 246 | 238 |
| 247 | |
| 248 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 239 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
| 249 if (!has_expression_temp_var()) { | 240 if (!has_expression_temp_var()) { |
| 250 LocalVariable* temp = | 241 LocalVariable* temp = |
| 251 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), | 242 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), |
| 252 Symbols::ExprTemp(), Object::dynamic_type()); | 243 Symbols::ExprTemp(), Object::dynamic_type()); |
| 253 ASSERT(temp != NULL); | 244 ASSERT(temp != NULL); |
| 254 set_expression_temp_var(temp); | 245 set_expression_temp_var(temp); |
| 255 } | 246 } |
| 256 ASSERT(has_expression_temp_var()); | 247 ASSERT(has_expression_temp_var()); |
| 257 return expression_temp_var(); | 248 return expression_temp_var(); |
| 258 } | 249 } |
| 259 | 250 |
| 260 | |
| 261 void ParsedFunction::EnsureFinallyReturnTemp(bool is_async) { | 251 void ParsedFunction::EnsureFinallyReturnTemp(bool is_async) { |
| 262 if (!has_finally_return_temp_var()) { | 252 if (!has_finally_return_temp_var()) { |
| 263 LocalVariable* temp = | 253 LocalVariable* temp = |
| 264 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), | 254 new (Z) LocalVariable(function_.token_pos(), function_.token_pos(), |
| 265 Symbols::FinallyRetVal(), Object::dynamic_type()); | 255 Symbols::FinallyRetVal(), Object::dynamic_type()); |
| 266 ASSERT(temp != NULL); | 256 ASSERT(temp != NULL); |
| 267 temp->set_is_final(); | 257 temp->set_is_final(); |
| 268 if (is_async) { | 258 if (is_async) { |
| 269 temp->set_is_captured(); | 259 temp->set_is_captured(); |
| 270 } | 260 } |
| 271 set_finally_return_temp_var(temp); | 261 set_finally_return_temp_var(temp); |
| 272 } | 262 } |
| 273 ASSERT(has_finally_return_temp_var()); | 263 ASSERT(has_finally_return_temp_var()); |
| 274 } | 264 } |
| 275 | 265 |
| 276 | |
| 277 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 266 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 278 ASSERT(node_sequence_ == NULL); | 267 ASSERT(node_sequence_ == NULL); |
| 279 ASSERT(node_sequence != NULL); | 268 ASSERT(node_sequence != NULL); |
| 280 node_sequence_ = node_sequence; | 269 node_sequence_ = node_sequence; |
| 281 } | 270 } |
| 282 | 271 |
| 283 | |
| 284 void ParsedFunction::SetRegExpCompileData( | 272 void ParsedFunction::SetRegExpCompileData( |
| 285 RegExpCompileData* regexp_compile_data) { | 273 RegExpCompileData* regexp_compile_data) { |
| 286 ASSERT(regexp_compile_data_ == NULL); | 274 ASSERT(regexp_compile_data_ == NULL); |
| 287 ASSERT(regexp_compile_data != NULL); | 275 ASSERT(regexp_compile_data != NULL); |
| 288 regexp_compile_data_ = regexp_compile_data; | 276 regexp_compile_data_ = regexp_compile_data; |
| 289 } | 277 } |
| 290 | 278 |
| 291 | |
| 292 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { | 279 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { |
| 293 // 'deferred_prefixes_' are used to invalidate code, but no invalidation is | 280 // 'deferred_prefixes_' are used to invalidate code, but no invalidation is |
| 294 // needed if --load_deferred_eagerly. | 281 // needed if --load_deferred_eagerly. |
| 295 ASSERT(!FLAG_load_deferred_eagerly); | 282 ASSERT(!FLAG_load_deferred_eagerly); |
| 296 ASSERT(prefix.is_deferred_load()); | 283 ASSERT(prefix.is_deferred_load()); |
| 297 ASSERT(!prefix.is_loaded()); | 284 ASSERT(!prefix.is_loaded()); |
| 298 for (intptr_t i = 0; i < deferred_prefixes_->length(); i++) { | 285 for (intptr_t i = 0; i < deferred_prefixes_->length(); i++) { |
| 299 if ((*deferred_prefixes_)[i]->raw() == prefix.raw()) { | 286 if ((*deferred_prefixes_)[i]->raw() == prefix.raw()) { |
| 300 return; | 287 return; |
| 301 } | 288 } |
| 302 } | 289 } |
| 303 deferred_prefixes_->Add(&LibraryPrefix::ZoneHandle(Z, prefix.raw())); | 290 deferred_prefixes_->Add(&LibraryPrefix::ZoneHandle(Z, prefix.raw())); |
| 304 } | 291 } |
| 305 | 292 |
| 306 | |
| 307 void ParsedFunction::AllocateVariables() { | 293 void ParsedFunction::AllocateVariables() { |
| 308 ASSERT(!function().IsIrregexpFunction()); | 294 ASSERT(!function().IsIrregexpFunction()); |
| 309 LocalScope* scope = node_sequence()->scope(); | 295 LocalScope* scope = node_sequence()->scope(); |
| 310 const intptr_t num_fixed_params = function().num_fixed_parameters(); | 296 const intptr_t num_fixed_params = function().num_fixed_parameters(); |
| 311 const intptr_t num_opt_params = function().NumOptionalParameters(); | 297 const intptr_t num_opt_params = function().NumOptionalParameters(); |
| 312 const intptr_t num_params = num_fixed_params + num_opt_params; | 298 const intptr_t num_params = num_fixed_params + num_opt_params; |
| 313 // Compute start indices to parameters and locals, and the number of | 299 // Compute start indices to parameters and locals, and the number of |
| 314 // parameters to copy. | 300 // parameters to copy. |
| 315 if (num_opt_params == 0) { | 301 if (num_opt_params == 0) { |
| 316 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 302 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
| (...skipping 14 matching lines...) Expand all Loading... |
| 331 bool found_captured_variables = false; | 317 bool found_captured_variables = false; |
| 332 int next_free_frame_index = scope->AllocateVariables( | 318 int next_free_frame_index = scope->AllocateVariables( |
| 333 first_parameter_index_, num_params, first_stack_local_index_, NULL, | 319 first_parameter_index_, num_params, first_stack_local_index_, NULL, |
| 334 &found_captured_variables); | 320 &found_captured_variables); |
| 335 | 321 |
| 336 // Frame indices are relative to the frame pointer and are decreasing. | 322 // Frame indices are relative to the frame pointer and are decreasing. |
| 337 ASSERT(next_free_frame_index <= first_stack_local_index_); | 323 ASSERT(next_free_frame_index <= first_stack_local_index_); |
| 338 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 324 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
| 339 } | 325 } |
| 340 | 326 |
| 341 | |
| 342 struct CatchParamDesc { | 327 struct CatchParamDesc { |
| 343 CatchParamDesc() | 328 CatchParamDesc() |
| 344 : token_pos(TokenPosition::kNoSource), | 329 : token_pos(TokenPosition::kNoSource), |
| 345 type(NULL), | 330 type(NULL), |
| 346 name(NULL), | 331 name(NULL), |
| 347 var(NULL) {} | 332 var(NULL) {} |
| 348 TokenPosition token_pos; | 333 TokenPosition token_pos; |
| 349 const AbstractType* type; | 334 const AbstractType* type; |
| 350 const String* name; | 335 const String* name; |
| 351 LocalVariable* var; | 336 LocalVariable* var; |
| 352 }; | 337 }; |
| 353 | 338 |
| 354 | |
| 355 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 339 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
| 356 ASSERT(function().IsIrregexpFunction()); | 340 ASSERT(function().IsIrregexpFunction()); |
| 357 ASSERT(function().NumOptionalParameters() == 0); | 341 ASSERT(function().NumOptionalParameters() == 0); |
| 358 const intptr_t num_params = function().num_fixed_parameters(); | 342 const intptr_t num_params = function().num_fixed_parameters(); |
| 359 ASSERT(num_params == RegExpMacroAssembler::kParamCount); | 343 ASSERT(num_params == RegExpMacroAssembler::kParamCount); |
| 360 // Compute start indices to parameters and locals, and the number of | 344 // Compute start indices to parameters and locals, and the number of |
| 361 // parameters to copy. | 345 // parameters to copy. |
| 362 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and | 346 // Parameter i will be at fp[kParamEndSlotFromFp + num_params - i] and |
| 363 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. | 347 // local variable j will be at fp[kFirstLocalSlotFromFp - j]. |
| 364 first_parameter_index_ = kParamEndSlotFromFp + num_params; | 348 first_parameter_index_ = kParamEndSlotFromFp + num_params; |
| 365 first_stack_local_index_ = kFirstLocalSlotFromFp; | 349 first_stack_local_index_ = kFirstLocalSlotFromFp; |
| 366 num_copied_params_ = 0; | 350 num_copied_params_ = 0; |
| 367 | 351 |
| 368 // Frame indices are relative to the frame pointer and are decreasing. | 352 // Frame indices are relative to the frame pointer and are decreasing. |
| 369 num_stack_locals_ = num_stack_locals; | 353 num_stack_locals_ = num_stack_locals; |
| 370 } | 354 } |
| 371 | 355 |
| 372 | |
| 373 struct Parser::Block : public ZoneAllocated { | 356 struct Parser::Block : public ZoneAllocated { |
| 374 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 357 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
| 375 : parent(outer_block), scope(local_scope), statements(seq) { | 358 : parent(outer_block), scope(local_scope), statements(seq) { |
| 376 ASSERT(scope != NULL); | 359 ASSERT(scope != NULL); |
| 377 ASSERT(statements != NULL); | 360 ASSERT(statements != NULL); |
| 378 } | 361 } |
| 379 Block* parent; // Enclosing block, or NULL if outermost. | 362 Block* parent; // Enclosing block, or NULL if outermost. |
| 380 LocalScope* scope; | 363 LocalScope* scope; |
| 381 SequenceNode* statements; | 364 SequenceNode* statements; |
| 382 }; | 365 }; |
| 383 | 366 |
| 384 | |
| 385 // Class which describes an inlined finally block which is used to generate | 367 // Class which describes an inlined finally block which is used to generate |
| 386 // inlined code for the finally blocks when there is an exit from a try | 368 // inlined code for the finally blocks when there is an exit from a try |
| 387 // block using 'return', 'break' or 'continue'. | 369 // block using 'return', 'break' or 'continue'. |
| 388 class Parser::TryStack : public ZoneAllocated { | 370 class Parser::TryStack : public ZoneAllocated { |
| 389 public: | 371 public: |
| 390 TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index) | 372 TryStack(Block* try_block, TryStack* outer_try, intptr_t try_index) |
| 391 : try_block_(try_block), | 373 : try_block_(try_block), |
| 392 inlined_finally_nodes_(), | 374 inlined_finally_nodes_(), |
| 393 outer_try_(outer_try), | 375 outer_try_(outer_try), |
| 394 try_index_(try_index), | 376 try_index_(try_index), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 418 GrowableArray<AstNode*> inlined_finally_nodes_; | 400 GrowableArray<AstNode*> inlined_finally_nodes_; |
| 419 TryStack* outer_try_; | 401 TryStack* outer_try_; |
| 420 const intptr_t try_index_; | 402 const intptr_t try_index_; |
| 421 bool inside_catch_; // True when parsing a catch clause of this try. | 403 bool inside_catch_; // True when parsing a catch clause of this try. |
| 422 bool inside_finally_; // True when parsing a finally clause of an inner try | 404 bool inside_finally_; // True when parsing a finally clause of an inner try |
| 423 // of this try. | 405 // of this try. |
| 424 | 406 |
| 425 DISALLOW_COPY_AND_ASSIGN(TryStack); | 407 DISALLOW_COPY_AND_ASSIGN(TryStack); |
| 426 }; | 408 }; |
| 427 | 409 |
| 428 | |
| 429 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { | 410 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { |
| 430 inlined_finally_nodes_.Add(node); | 411 inlined_finally_nodes_.Add(node); |
| 431 } | 412 } |
| 432 | 413 |
| 433 | |
| 434 void Parser::TryStack::RemoveJumpToLabel(SourceLabel* label) { | 414 void Parser::TryStack::RemoveJumpToLabel(SourceLabel* label) { |
| 435 int i = 0; | 415 int i = 0; |
| 436 while (i < inlined_finally_nodes_.length()) { | 416 while (i < inlined_finally_nodes_.length()) { |
| 437 if (inlined_finally_nodes_[i]->IsJumpNode()) { | 417 if (inlined_finally_nodes_[i]->IsJumpNode()) { |
| 438 JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode(); | 418 JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode(); |
| 439 if (jump->label() == label) { | 419 if (jump->label() == label) { |
| 440 // Shift remaining entries left and delete last entry. | 420 // Shift remaining entries left and delete last entry. |
| 441 for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) { | 421 for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) { |
| 442 inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j]; | 422 inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j]; |
| 443 } | 423 } |
| 444 inlined_finally_nodes_.RemoveLast(); | 424 inlined_finally_nodes_.RemoveLast(); |
| 445 continue; | 425 continue; |
| 446 } | 426 } |
| 447 } | 427 } |
| 448 i++; | 428 i++; |
| 449 } | 429 } |
| 450 } | 430 } |
| 451 | 431 |
| 452 | |
| 453 // For parsing a compilation unit. | 432 // For parsing a compilation unit. |
| 454 Parser::Parser(const Script& script, | 433 Parser::Parser(const Script& script, |
| 455 const Library& library, | 434 const Library& library, |
| 456 TokenPosition token_pos) | 435 TokenPosition token_pos) |
| 457 : thread_(Thread::Current()), | 436 : thread_(Thread::Current()), |
| 458 isolate_(thread()->isolate()), | 437 isolate_(thread()->isolate()), |
| 459 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), | 438 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), |
| 460 script_(Script::Handle(zone(), script.raw())), | 439 script_(Script::Handle(zone(), script.raw())), |
| 461 tokens_iterator_(zone(), | 440 tokens_iterator_(zone(), |
| 462 TokenStream::Handle(zone(), script.tokens()), | 441 TokenStream::Handle(zone(), script.tokens()), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 475 try_stack_(NULL), | 454 try_stack_(NULL), |
| 476 last_used_try_index_(0), | 455 last_used_try_index_(0), |
| 477 unregister_pending_function_(false), | 456 unregister_pending_function_(false), |
| 478 async_temp_scope_(NULL), | 457 async_temp_scope_(NULL), |
| 479 trace_indent_(0), | 458 trace_indent_(0), |
| 480 recursion_counter_(0) { | 459 recursion_counter_(0) { |
| 481 ASSERT(tokens_iterator_.IsValid()); | 460 ASSERT(tokens_iterator_.IsValid()); |
| 482 ASSERT(!library.IsNull()); | 461 ASSERT(!library.IsNull()); |
| 483 } | 462 } |
| 484 | 463 |
| 485 | |
| 486 // For parsing a function. | 464 // For parsing a function. |
| 487 Parser::Parser(const Script& script, | 465 Parser::Parser(const Script& script, |
| 488 ParsedFunction* parsed_function, | 466 ParsedFunction* parsed_function, |
| 489 TokenPosition token_pos) | 467 TokenPosition token_pos) |
| 490 : thread_(Thread::Current()), | 468 : thread_(Thread::Current()), |
| 491 isolate_(thread()->isolate()), | 469 isolate_(thread()->isolate()), |
| 492 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), | 470 allocation_space_(thread_->IsMutatorThread() ? Heap::kNew : Heap::kOld), |
| 493 script_(Script::Handle(zone(), script.raw())), | 471 script_(Script::Handle(zone(), script.raw())), |
| 494 tokens_iterator_(zone(), | 472 tokens_iterator_(zone(), |
| 495 TokenStream::Handle(zone(), script.tokens()), | 473 TokenStream::Handle(zone(), script.tokens()), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 514 last_used_try_index_(0), | 492 last_used_try_index_(0), |
| 515 unregister_pending_function_(false), | 493 unregister_pending_function_(false), |
| 516 async_temp_scope_(NULL), | 494 async_temp_scope_(NULL), |
| 517 trace_indent_(0), | 495 trace_indent_(0), |
| 518 recursion_counter_(0) { | 496 recursion_counter_(0) { |
| 519 ASSERT(tokens_iterator_.IsValid()); | 497 ASSERT(tokens_iterator_.IsValid()); |
| 520 ASSERT(!current_function().IsNull()); | 498 ASSERT(!current_function().IsNull()); |
| 521 EnsureExpressionTemp(); | 499 EnsureExpressionTemp(); |
| 522 } | 500 } |
| 523 | 501 |
| 524 | |
| 525 Parser::~Parser() { | 502 Parser::~Parser() { |
| 526 if (unregister_pending_function_) { | 503 if (unregister_pending_function_) { |
| 527 const GrowableObjectArray& pending_functions = | 504 const GrowableObjectArray& pending_functions = |
| 528 GrowableObjectArray::Handle(T->pending_functions()); | 505 GrowableObjectArray::Handle(T->pending_functions()); |
| 529 ASSERT(!pending_functions.IsNull()); | 506 ASSERT(!pending_functions.IsNull()); |
| 530 ASSERT(pending_functions.Length() > 0); | 507 ASSERT(pending_functions.Length() > 0); |
| 531 ASSERT(pending_functions.At(pending_functions.Length() - 1) == | 508 ASSERT(pending_functions.At(pending_functions.Length() - 1) == |
| 532 current_function().raw()); | 509 current_function().raw()); |
| 533 pending_functions.RemoveLast(); | 510 pending_functions.RemoveLast(); |
| 534 } | 511 } |
| 535 } | 512 } |
| 536 | 513 |
| 537 | |
| 538 // Each try in this function gets its own try index. | 514 // Each try in this function gets its own try index. |
| 539 // See definition of RawPcDescriptors::PcDescriptor. | 515 // See definition of RawPcDescriptors::PcDescriptor. |
| 540 int16_t Parser::AllocateTryIndex() { | 516 int16_t Parser::AllocateTryIndex() { |
| 541 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 517 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
| 542 ReportError("too many nested try statements"); | 518 ReportError("too many nested try statements"); |
| 543 } | 519 } |
| 544 return last_used_try_index_++; | 520 return last_used_try_index_++; |
| 545 } | 521 } |
| 546 | 522 |
| 547 | |
| 548 void Parser::SetScript(const Script& script, TokenPosition token_pos) { | 523 void Parser::SetScript(const Script& script, TokenPosition token_pos) { |
| 549 script_ = script.raw(); | 524 script_ = script.raw(); |
| 550 tokens_iterator_.SetStream(TokenStream::Handle(Z, script.tokens()), | 525 tokens_iterator_.SetStream(TokenStream::Handle(Z, script.tokens()), |
| 551 token_pos); | 526 token_pos); |
| 552 token_kind_ = Token::kILLEGAL; | 527 token_kind_ = Token::kILLEGAL; |
| 553 } | 528 } |
| 554 | 529 |
| 555 | |
| 556 bool Parser::SetAllowFunctionLiterals(bool value) { | 530 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 557 bool current_value = allow_function_literals_; | 531 bool current_value = allow_function_literals_; |
| 558 allow_function_literals_ = value; | 532 allow_function_literals_ = value; |
| 559 return current_value; | 533 return current_value; |
| 560 } | 534 } |
| 561 | 535 |
| 562 | |
| 563 const Function& Parser::current_function() const { | 536 const Function& Parser::current_function() const { |
| 564 ASSERT(parsed_function() != NULL); | 537 ASSERT(parsed_function() != NULL); |
| 565 return parsed_function()->function(); | 538 return parsed_function()->function(); |
| 566 } | 539 } |
| 567 | 540 |
| 568 | |
| 569 const Function& Parser::innermost_function() const { | 541 const Function& Parser::innermost_function() const { |
| 570 return innermost_function_; | 542 return innermost_function_; |
| 571 } | 543 } |
| 572 | 544 |
| 573 | |
| 574 int Parser::FunctionLevel() const { | 545 int Parser::FunctionLevel() const { |
| 575 if (current_block_ != NULL) { | 546 if (current_block_ != NULL) { |
| 576 return current_block_->scope->function_level(); | 547 return current_block_->scope->function_level(); |
| 577 } | 548 } |
| 578 return 0; | 549 return 0; |
| 579 } | 550 } |
| 580 | 551 |
| 581 | |
| 582 const Class& Parser::current_class() const { | 552 const Class& Parser::current_class() const { |
| 583 return current_class_; | 553 return current_class_; |
| 584 } | 554 } |
| 585 | 555 |
| 586 | |
| 587 void Parser::set_current_class(const Class& value) { | 556 void Parser::set_current_class(const Class& value) { |
| 588 current_class_ = value.raw(); | 557 current_class_ = value.raw(); |
| 589 } | 558 } |
| 590 | 559 |
| 591 | |
| 592 void Parser::SetPosition(TokenPosition position) { | 560 void Parser::SetPosition(TokenPosition position) { |
| 593 tokens_iterator_.SetCurrentPosition(position); | 561 tokens_iterator_.SetCurrentPosition(position); |
| 594 token_kind_ = Token::kILLEGAL; | 562 token_kind_ = Token::kILLEGAL; |
| 595 prev_token_pos_ = position; | 563 prev_token_pos_ = position; |
| 596 } | 564 } |
| 597 | 565 |
| 598 | |
| 599 // Set state and increments generational count so that thge background compiler | 566 // Set state and increments generational count so that thge background compiler |
| 600 // can detect if loading/top-level-parsing occured during compilation. | 567 // can detect if loading/top-level-parsing occured during compilation. |
| 601 class TopLevelParsingScope : public StackResource { | 568 class TopLevelParsingScope : public StackResource { |
| 602 public: | 569 public: |
| 603 explicit TopLevelParsingScope(Thread* thread) : StackResource(thread) { | 570 explicit TopLevelParsingScope(Thread* thread) : StackResource(thread) { |
| 604 isolate()->IncrTopLevelParsingCount(); | 571 isolate()->IncrTopLevelParsingCount(); |
| 605 } | 572 } |
| 606 ~TopLevelParsingScope() { | 573 ~TopLevelParsingScope() { |
| 607 isolate()->DecrTopLevelParsingCount(); | 574 isolate()->DecrTopLevelParsingCount(); |
| 608 isolate()->IncrLoadingInvalidationGen(); | 575 isolate()->IncrLoadingInvalidationGen(); |
| 609 } | 576 } |
| 610 }; | 577 }; |
| 611 | 578 |
| 612 | |
| 613 void Parser::ParseCompilationUnit(const Library& library, | 579 void Parser::ParseCompilationUnit(const Library& library, |
| 614 const Script& script) { | 580 const Script& script) { |
| 615 Thread* thread = Thread::Current(); | 581 Thread* thread = Thread::Current(); |
| 616 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 582 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
| 617 CSTAT_TIMER_SCOPE(thread, parser_timer); | 583 CSTAT_TIMER_SCOPE(thread, parser_timer); |
| 618 #ifndef PRODUCT | 584 #ifndef PRODUCT |
| 619 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 585 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
| 620 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 586 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
| 621 "CompileTopLevel"); | 587 "CompileTopLevel"); |
| 622 if (tds.enabled()) { | 588 if (tds.enabled()) { |
| 623 tds.SetNumArguments(1); | 589 tds.SetNumArguments(1); |
| 624 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); | 590 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); |
| 625 } | 591 } |
| 626 #endif | 592 #endif |
| 627 | 593 |
| 628 TopLevelParsingScope scope(thread); | 594 TopLevelParsingScope scope(thread); |
| 629 Parser parser(script, library, TokenPosition::kMinSource); | 595 Parser parser(script, library, TokenPosition::kMinSource); |
| 630 parser.ParseTopLevel(); | 596 parser.ParseTopLevel(); |
| 631 } | 597 } |
| 632 | 598 |
| 633 | |
| 634 void Parser::ComputeCurrentToken() { | 599 void Parser::ComputeCurrentToken() { |
| 635 ASSERT(token_kind_ == Token::kILLEGAL); | 600 ASSERT(token_kind_ == Token::kILLEGAL); |
| 636 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 601 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 637 if (token_kind_ == Token::kERROR) { | 602 if (token_kind_ == Token::kERROR) { |
| 638 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 603 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
| 639 } | 604 } |
| 640 } | 605 } |
| 641 | 606 |
| 642 | |
| 643 Token::Kind Parser::LookaheadToken(int num_tokens) { | 607 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| 644 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 608 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
| 645 } | 609 } |
| 646 | 610 |
| 647 | |
| 648 String* Parser::CurrentLiteral() const { | 611 String* Parser::CurrentLiteral() const { |
| 649 String& result = String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); | 612 String& result = String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); |
| 650 return &result; | 613 return &result; |
| 651 } | 614 } |
| 652 | 615 |
| 653 | |
| 654 RawDouble* Parser::CurrentDoubleLiteral() const { | 616 RawDouble* Parser::CurrentDoubleLiteral() const { |
| 655 literal_token_ ^= tokens_iterator_.CurrentToken(); | 617 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 656 ASSERT(literal_token_.kind() == Token::kDOUBLE); | 618 ASSERT(literal_token_.kind() == Token::kDOUBLE); |
| 657 return Double::RawCast(literal_token_.value()); | 619 return Double::RawCast(literal_token_.value()); |
| 658 } | 620 } |
| 659 | 621 |
| 660 | |
| 661 RawInteger* Parser::CurrentIntegerLiteral() const { | 622 RawInteger* Parser::CurrentIntegerLiteral() const { |
| 662 literal_token_ ^= tokens_iterator_.CurrentToken(); | 623 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 663 ASSERT(literal_token_.kind() == Token::kINTEGER); | 624 ASSERT(literal_token_.kind() == Token::kINTEGER); |
| 664 RawInteger* ri = Integer::RawCast(literal_token_.value()); | 625 RawInteger* ri = Integer::RawCast(literal_token_.value()); |
| 665 return ri; | 626 return ri; |
| 666 } | 627 } |
| 667 | 628 |
| 668 | |
| 669 struct ParamDesc { | 629 struct ParamDesc { |
| 670 ParamDesc() | 630 ParamDesc() |
| 671 : type(NULL), | 631 : type(NULL), |
| 672 name_pos(TokenPosition::kNoSource), | 632 name_pos(TokenPosition::kNoSource), |
| 673 name(NULL), | 633 name(NULL), |
| 674 default_value(NULL), | 634 default_value(NULL), |
| 675 metadata(NULL), | 635 metadata(NULL), |
| 676 var(NULL), | 636 var(NULL), |
| 677 is_final(false), | 637 is_final(false), |
| 678 is_field_initializer(false), | 638 is_field_initializer(false), |
| 679 has_explicit_type(false), | 639 has_explicit_type(false), |
| 680 is_covariant(false) {} | 640 is_covariant(false) {} |
| 681 const AbstractType* type; | 641 const AbstractType* type; |
| 682 TokenPosition name_pos; | 642 TokenPosition name_pos; |
| 683 const String* name; | 643 const String* name; |
| 684 const Instance* default_value; // NULL if not an optional parameter. | 644 const Instance* default_value; // NULL if not an optional parameter. |
| 685 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 645 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
| 686 LocalVariable* var; // Scope variable allocated for this parameter. | 646 LocalVariable* var; // Scope variable allocated for this parameter. |
| 687 bool is_final; | 647 bool is_final; |
| 688 bool is_field_initializer; | 648 bool is_field_initializer; |
| 689 bool has_explicit_type; | 649 bool has_explicit_type; |
| 690 bool is_covariant; | 650 bool is_covariant; |
| 691 }; | 651 }; |
| 692 | 652 |
| 693 | |
| 694 struct ParamList { | 653 struct ParamList { |
| 695 ParamList() { Clear(); } | 654 ParamList() { Clear(); } |
| 696 | 655 |
| 697 void Clear() { | 656 void Clear() { |
| 698 num_fixed_parameters = 0; | 657 num_fixed_parameters = 0; |
| 699 num_optional_parameters = 0; | 658 num_optional_parameters = 0; |
| 700 has_optional_positional_parameters = false; | 659 has_optional_positional_parameters = false; |
| 701 has_optional_named_parameters = false; | 660 has_optional_named_parameters = false; |
| 702 has_explicit_default_values = false; | 661 has_explicit_default_values = false; |
| 703 has_field_initializer = false; | 662 has_field_initializer = false; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 bool has_optional_positional_parameters; | 721 bool has_optional_positional_parameters; |
| 763 bool has_optional_named_parameters; | 722 bool has_optional_named_parameters; |
| 764 bool has_explicit_default_values; | 723 bool has_explicit_default_values; |
| 765 bool has_field_initializer; | 724 bool has_field_initializer; |
| 766 bool has_covariant; | 725 bool has_covariant; |
| 767 bool implicitly_final; | 726 bool implicitly_final; |
| 768 bool skipped; | 727 bool skipped; |
| 769 ZoneGrowableArray<ParamDesc>* parameters; | 728 ZoneGrowableArray<ParamDesc>* parameters; |
| 770 }; | 729 }; |
| 771 | 730 |
| 772 | |
| 773 struct MemberDesc { | 731 struct MemberDesc { |
| 774 MemberDesc() { Clear(); } | 732 MemberDesc() { Clear(); } |
| 775 | 733 |
| 776 void Clear() { | 734 void Clear() { |
| 777 has_abstract = false; | 735 has_abstract = false; |
| 778 has_external = false; | 736 has_external = false; |
| 779 has_covariant = false; | 737 has_covariant = false; |
| 780 has_final = false; | 738 has_final = false; |
| 781 has_const = false; | 739 has_const = false; |
| 782 has_static = false; | 740 has_static = false; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 // For constructors: NULL for unnamed constructor, | 803 // For constructors: NULL for unnamed constructor, |
| 846 // identifier after classname for named constructors. | 804 // identifier after classname for named constructors. |
| 847 // For getters and setters: unmangled name. | 805 // For getters and setters: unmangled name. |
| 848 String* dict_name; | 806 String* dict_name; |
| 849 ParamList params; | 807 ParamList params; |
| 850 RawFunction::Kind kind; | 808 RawFunction::Kind kind; |
| 851 // NULL for functions, field object for static or instance fields. | 809 // NULL for functions, field object for static or instance fields. |
| 852 Field* field_; | 810 Field* field_; |
| 853 }; | 811 }; |
| 854 | 812 |
| 855 | |
| 856 class ClassDesc : public ValueObject { | 813 class ClassDesc : public ValueObject { |
| 857 public: | 814 public: |
| 858 ClassDesc(Zone* zone, | 815 ClassDesc(Zone* zone, |
| 859 const Class& cls, | 816 const Class& cls, |
| 860 const String& cls_name, | 817 const String& cls_name, |
| 861 bool is_interface, | 818 bool is_interface, |
| 862 TokenPosition token_pos) | 819 TokenPosition token_pos) |
| 863 : zone_(zone), | 820 : zone_(zone), |
| 864 clazz_(cls), | 821 clazz_(cls), |
| 865 class_name_(cls_name), | 822 class_name_(cls_name), |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 private: | 877 private: |
| 921 Zone* zone_; | 878 Zone* zone_; |
| 922 const Class& clazz_; | 879 const Class& clazz_; |
| 923 const String& class_name_; | 880 const String& class_name_; |
| 924 TokenPosition token_pos_; // Token index of "class" keyword. | 881 TokenPosition token_pos_; // Token index of "class" keyword. |
| 925 GrowableArray<const Function*> functions_; | 882 GrowableArray<const Function*> functions_; |
| 926 GrowableArray<const Field*> fields_; | 883 GrowableArray<const Field*> fields_; |
| 927 GrowableArray<MemberDesc> members_; | 884 GrowableArray<MemberDesc> members_; |
| 928 }; | 885 }; |
| 929 | 886 |
| 930 | |
| 931 class TopLevel : public ValueObject { | 887 class TopLevel : public ValueObject { |
| 932 public: | 888 public: |
| 933 explicit TopLevel(Zone* zone) | 889 explicit TopLevel(Zone* zone) |
| 934 : zone_(zone), fields_(zone, 4), functions_(zone, 4) {} | 890 : zone_(zone), fields_(zone, 4), functions_(zone, 4) {} |
| 935 | 891 |
| 936 void AddField(const Field& field) { | 892 void AddField(const Field& field) { |
| 937 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); | 893 fields_.Add(&Field::ZoneHandle(zone_, field.raw())); |
| 938 } | 894 } |
| 939 | 895 |
| 940 void AddFunction(const Function& function) { | 896 void AddFunction(const Function& function) { |
| 941 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 897 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
| 942 } | 898 } |
| 943 | 899 |
| 944 const GrowableArray<const Field*>& fields() const { return fields_; } | 900 const GrowableArray<const Field*>& fields() const { return fields_; } |
| 945 | 901 |
| 946 const GrowableArray<const Function*>& functions() const { return functions_; } | 902 const GrowableArray<const Function*>& functions() const { return functions_; } |
| 947 | 903 |
| 948 private: | 904 private: |
| 949 Zone* zone_; | 905 Zone* zone_; |
| 950 GrowableArray<const Field*> fields_; | 906 GrowableArray<const Field*> fields_; |
| 951 GrowableArray<const Function*> functions_; | 907 GrowableArray<const Function*> functions_; |
| 952 }; | 908 }; |
| 953 | 909 |
| 954 | |
| 955 void Parser::ParseClass(const Class& cls) { | 910 void Parser::ParseClass(const Class& cls) { |
| 956 Thread* thread = Thread::Current(); | 911 Thread* thread = Thread::Current(); |
| 957 Zone* zone = thread->zone(); | 912 Zone* zone = thread->zone(); |
| 958 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); | 913 const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed); |
| 959 #ifndef PRODUCT | 914 #ifndef PRODUCT |
| 960 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 915 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
| 961 "ParseClass"); | 916 "ParseClass"); |
| 962 if (tds.enabled()) { | 917 if (tds.enabled()) { |
| 963 tds.SetNumArguments(1); | 918 tds.SetNumArguments(1); |
| 964 tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString()); | 919 tds.CopyArgument(0, "class", String::Handle(cls.Name()).ToCString()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 976 CSTAT_TIMER_SCOPE(thread, parser_timer); | 931 CSTAT_TIMER_SCOPE(thread, parser_timer); |
| 977 const Script& script = Script::Handle(zone, cls.script()); | 932 const Script& script = Script::Handle(zone, cls.script()); |
| 978 const Library& lib = Library::Handle(zone, cls.library()); | 933 const Library& lib = Library::Handle(zone, cls.library()); |
| 979 Parser parser(script, lib, cls.token_pos()); | 934 Parser parser(script, lib, cls.token_pos()); |
| 980 parser.ParseEnumDefinition(cls); | 935 parser.ParseEnumDefinition(cls); |
| 981 } | 936 } |
| 982 const int64_t num_tokes_after = STAT_VALUE(thread, num_tokens_consumed); | 937 const int64_t num_tokes_after = STAT_VALUE(thread, num_tokens_consumed); |
| 983 INC_STAT(thread, num_class_tokens, num_tokes_after - num_tokes_before); | 938 INC_STAT(thread, num_class_tokens, num_tokes_after - num_tokes_before); |
| 984 } | 939 } |
| 985 | 940 |
| 986 | |
| 987 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, | 941 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, |
| 988 TokenPosition* start, | 942 TokenPosition* start, |
| 989 TokenPosition* end) { | 943 TokenPosition* end) { |
| 990 if (!field.has_initializer()) { | 944 if (!field.has_initializer()) { |
| 991 return false; | 945 return false; |
| 992 } | 946 } |
| 993 Thread* thread = Thread::Current(); | 947 Thread* thread = Thread::Current(); |
| 994 Zone* zone = thread->zone(); | 948 Zone* zone = thread->zone(); |
| 995 const Class& cls = Class::Handle(zone, field.Owner()); | 949 const Class& cls = Class::Handle(zone, field.Owner()); |
| 996 const Script& script = Script::Handle(zone, cls.script()); | 950 const Script& script = Script::Handle(zone, cls.script()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1013 *start = TokenPos(); | 967 *start = TokenPos(); |
| 1014 if (IsFunctionLiteral()) { | 968 if (IsFunctionLiteral()) { |
| 1015 SkipExpr(); | 969 SkipExpr(); |
| 1016 *end = PrevTokenPos(); | 970 *end = PrevTokenPos(); |
| 1017 return true; | 971 return true; |
| 1018 } | 972 } |
| 1019 | 973 |
| 1020 return false; | 974 return false; |
| 1021 } | 975 } |
| 1022 | 976 |
| 1023 | |
| 1024 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 977 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
| 1025 ASSERT(!func.IsNull()); | 978 ASSERT(!func.IsNull()); |
| 1026 LongJumpScope jump; | 979 LongJumpScope jump; |
| 1027 if (setjmp(*jump.Set()) == 0) { | 980 if (setjmp(*jump.Set()) == 0) { |
| 1028 Thread* thread = Thread::Current(); | 981 Thread* thread = Thread::Current(); |
| 1029 StackZone stack_zone(thread); | 982 StackZone stack_zone(thread); |
| 1030 Zone* zone = stack_zone.GetZone(); | 983 Zone* zone = stack_zone.GetZone(); |
| 1031 const Script& script = Script::Handle(zone, func.script()); | 984 const Script& script = Script::Handle(zone, func.script()); |
| 1032 const Class& owner = Class::Handle(zone, func.Owner()); | 985 const Class& owner = Class::Handle(zone, func.Owner()); |
| 1033 ASSERT(!owner.IsNull()); | 986 ASSERT(!owner.IsNull()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 Thread* thread = Thread::Current(); | 1021 Thread* thread = Thread::Current(); |
| 1069 Error& error = Error::Handle(); | 1022 Error& error = Error::Handle(); |
| 1070 error = thread->sticky_error(); | 1023 error = thread->sticky_error(); |
| 1071 thread->clear_sticky_error(); | 1024 thread->clear_sticky_error(); |
| 1072 return error.raw(); | 1025 return error.raw(); |
| 1073 } | 1026 } |
| 1074 UNREACHABLE(); | 1027 UNREACHABLE(); |
| 1075 return Object::null(); | 1028 return Object::null(); |
| 1076 } | 1029 } |
| 1077 | 1030 |
| 1078 | |
| 1079 bool Parser::ParseFormalParameters(const Function& func, ParamList* params) { | 1031 bool Parser::ParseFormalParameters(const Function& func, ParamList* params) { |
| 1080 ASSERT(!func.IsNull()); | 1032 ASSERT(!func.IsNull()); |
| 1081 // This is currently only used for constructors. To handle all kinds | 1033 // This is currently only used for constructors. To handle all kinds |
| 1082 // of functions, special cases for getters and possibly other kinds | 1034 // of functions, special cases for getters and possibly other kinds |
| 1083 // need to be added. | 1035 // need to be added. |
| 1084 ASSERT(func.kind() == RawFunction::kConstructor); | 1036 ASSERT(func.kind() == RawFunction::kConstructor); |
| 1085 ASSERT(!func.IsRedirectingFactory()); | 1037 ASSERT(!func.IsRedirectingFactory()); |
| 1086 // Implicit constructors have no source, no user-defined formal parameters. | 1038 // Implicit constructors have no source, no user-defined formal parameters. |
| 1087 if (func.IsImplicitConstructor()) { | 1039 if (func.IsImplicitConstructor()) { |
| 1088 return true; | 1040 return true; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1105 return true; | 1057 return true; |
| 1106 } else { | 1058 } else { |
| 1107 Thread::Current()->clear_sticky_error(); | 1059 Thread::Current()->clear_sticky_error(); |
| 1108 params->Clear(); | 1060 params->Clear(); |
| 1109 return false; | 1061 return false; |
| 1110 } | 1062 } |
| 1111 UNREACHABLE(); | 1063 UNREACHABLE(); |
| 1112 return false; | 1064 return false; |
| 1113 } | 1065 } |
| 1114 | 1066 |
| 1115 | |
| 1116 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 1067 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 1117 Thread* thread = parsed_function->thread(); | 1068 Thread* thread = parsed_function->thread(); |
| 1118 ASSERT(thread == Thread::Current()); | 1069 ASSERT(thread == Thread::Current()); |
| 1119 Zone* zone = thread->zone(); | 1070 Zone* zone = thread->zone(); |
| 1120 CSTAT_TIMER_SCOPE(thread, parser_timer); | 1071 CSTAT_TIMER_SCOPE(thread, parser_timer); |
| 1121 INC_STAT(thread, num_functions_parsed, 1); | 1072 INC_STAT(thread, num_functions_parsed, 1); |
| 1122 #ifndef PRODUCT | 1073 #ifndef PRODUCT |
| 1123 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 1074 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
| 1124 FLAG_profile_vm); | 1075 FLAG_profile_vm); |
| 1125 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 1076 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 ((instantiator != NULL) && instantiator->is_captured())) { | 1165 ((instantiator != NULL) && instantiator->is_captured())) { |
| 1215 parsed_function->set_instantiator(instantiator); | 1166 parsed_function->set_instantiator(instantiator); |
| 1216 } | 1167 } |
| 1217 } | 1168 } |
| 1218 // ParseFunc has recorded the generic function type arguments variable. | 1169 // ParseFunc has recorded the generic function type arguments variable. |
| 1219 ASSERT(!FLAG_reify_generic_functions || | 1170 ASSERT(!FLAG_reify_generic_functions || |
| 1220 !parser.current_function().IsGeneric() || | 1171 !parser.current_function().IsGeneric() || |
| 1221 (parsed_function->function_type_arguments() != NULL)); | 1172 (parsed_function->function_type_arguments() != NULL)); |
| 1222 } | 1173 } |
| 1223 | 1174 |
| 1224 | |
| 1225 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 1175 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
| 1226 LongJumpScope jump; | 1176 LongJumpScope jump; |
| 1227 if (setjmp(*jump.Set()) == 0) { | 1177 if (setjmp(*jump.Set()) == 0) { |
| 1228 Thread* thread = Thread::Current(); | 1178 Thread* thread = Thread::Current(); |
| 1229 StackZone stack_zone(thread); | 1179 StackZone stack_zone(thread); |
| 1230 Zone* zone = stack_zone.GetZone(); | 1180 Zone* zone = stack_zone.GetZone(); |
| 1231 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); | 1181 const Class& owner_class = Class::Handle(zone, meta_data.Owner()); |
| 1232 const Script& script = Script::Handle(zone, meta_data.Script()); | 1182 const Script& script = Script::Handle(zone, meta_data.Script()); |
| 1233 const TokenPosition token_pos = meta_data.token_pos(); | 1183 const TokenPosition token_pos = meta_data.token_pos(); |
| 1234 // Parsing metadata can involve following paths in the parser that are | 1184 // Parsing metadata can involve following paths in the parser that are |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1258 Zone* zone = stack_zone.GetZone(); | 1208 Zone* zone = stack_zone.GetZone(); |
| 1259 Error& error = Error::Handle(zone); | 1209 Error& error = Error::Handle(zone); |
| 1260 error = thread->sticky_error(); | 1210 error = thread->sticky_error(); |
| 1261 thread->clear_sticky_error(); | 1211 thread->clear_sticky_error(); |
| 1262 return error.raw(); | 1212 return error.raw(); |
| 1263 } | 1213 } |
| 1264 UNREACHABLE(); | 1214 UNREACHABLE(); |
| 1265 return Object::null(); | 1215 return Object::null(); |
| 1266 } | 1216 } |
| 1267 | 1217 |
| 1268 | |
| 1269 RawArray* Parser::EvaluateMetadata() { | 1218 RawArray* Parser::EvaluateMetadata() { |
| 1270 CheckToken(Token::kAT, "Metadata character '@' expected"); | 1219 CheckToken(Token::kAT, "Metadata character '@' expected"); |
| 1271 GrowableObjectArray& meta_values = | 1220 GrowableObjectArray& meta_values = |
| 1272 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 1221 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 1273 while (CurrentToken() == Token::kAT) { | 1222 while (CurrentToken() == Token::kAT) { |
| 1274 ConsumeToken(); | 1223 ConsumeToken(); |
| 1275 TokenPosition expr_pos = TokenPos(); | 1224 TokenPosition expr_pos = TokenPos(); |
| 1276 if (!IsIdentifier()) { | 1225 if (!IsIdentifier()) { |
| 1277 ExpectIdentifier("identifier expected"); | 1226 ExpectIdentifier("identifier expected"); |
| 1278 } | 1227 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 } | 1281 } |
| 1333 if (expr->EvalConstExpr() == NULL) { | 1282 if (expr->EvalConstExpr() == NULL) { |
| 1334 ReportError(expr_pos, "expression must be a compile-time constant"); | 1283 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 1335 } | 1284 } |
| 1336 const Instance& val = EvaluateConstExpr(expr_pos, expr); | 1285 const Instance& val = EvaluateConstExpr(expr_pos, expr); |
| 1337 meta_values.Add(val, Heap::kOld); | 1286 meta_values.Add(val, Heap::kOld); |
| 1338 } | 1287 } |
| 1339 return Array::MakeFixedLength(meta_values); | 1288 return Array::MakeFixedLength(meta_values); |
| 1340 } | 1289 } |
| 1341 | 1290 |
| 1342 | |
| 1343 SequenceNode* Parser::ParseStaticInitializer() { | 1291 SequenceNode* Parser::ParseStaticInitializer() { |
| 1344 ExpectIdentifier("field name expected"); | 1292 ExpectIdentifier("field name expected"); |
| 1345 CheckToken(Token::kASSIGN, "field initialier expected"); | 1293 CheckToken(Token::kASSIGN, "field initialier expected"); |
| 1346 ConsumeToken(); | 1294 ConsumeToken(); |
| 1347 OpenFunctionBlock(parsed_function()->function()); | 1295 OpenFunctionBlock(parsed_function()->function()); |
| 1348 TokenPosition expr_pos = TokenPos(); | 1296 TokenPosition expr_pos = TokenPos(); |
| 1349 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1297 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1350 ReturnNode* ret = new (Z) ReturnNode(expr_pos, expr); | 1298 ReturnNode* ret = new (Z) ReturnNode(expr_pos, expr); |
| 1351 current_block_->statements->Add(ret); | 1299 current_block_->statements->Add(ret); |
| 1352 return CloseBlock(); | 1300 return CloseBlock(); |
| 1353 } | 1301 } |
| 1354 | 1302 |
| 1355 | |
| 1356 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1303 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
| 1357 ASSERT(field.is_static()); | 1304 ASSERT(field.is_static()); |
| 1358 Thread* thread = Thread::Current(); | 1305 Thread* thread = Thread::Current(); |
| 1359 // TODO(koda): Should there be a StackZone here? | 1306 // TODO(koda): Should there be a StackZone here? |
| 1360 Zone* zone = thread->zone(); | 1307 Zone* zone = thread->zone(); |
| 1361 #ifndef PRODUCT | 1308 #ifndef PRODUCT |
| 1362 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, | 1309 VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId, |
| 1363 FLAG_profile_vm); | 1310 FLAG_profile_vm); |
| 1364 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 1311 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
| 1365 "ParseStaticFieldInitializer"); | 1312 "ParseStaticFieldInitializer"); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 body->scope()->AddVariable(parsed_function->current_context_var()); | 1349 body->scope()->AddVariable(parsed_function->current_context_var()); |
| 1403 if (parsed_function->has_finally_return_temp_var()) { | 1350 if (parsed_function->has_finally_return_temp_var()) { |
| 1404 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); | 1351 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); |
| 1405 } | 1352 } |
| 1406 // The instantiator is not required in a static expression. | 1353 // The instantiator is not required in a static expression. |
| 1407 ASSERT(!parser.IsInstantiatorRequired()); | 1354 ASSERT(!parser.IsInstantiatorRequired()); |
| 1408 | 1355 |
| 1409 return parsed_function; | 1356 return parsed_function; |
| 1410 } | 1357 } |
| 1411 | 1358 |
| 1412 | |
| 1413 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 1359 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 1414 TRACE_PARSER("ParseStaticFinalGetter"); | 1360 TRACE_PARSER("ParseStaticFinalGetter"); |
| 1415 ASSERT(func.num_fixed_parameters() == 0); // static. | 1361 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1416 ASSERT(!func.HasOptionalParameters()); | 1362 ASSERT(!func.HasOptionalParameters()); |
| 1417 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1363 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 1418 OpenFunctionBlock(func); | 1364 OpenFunctionBlock(func); |
| 1419 TokenPosition ident_pos = TokenPos(); | 1365 TokenPosition ident_pos = TokenPos(); |
| 1420 const String& field_name = *ExpectIdentifier("field name expected"); | 1366 const String& field_name = *ExpectIdentifier("field name expected"); |
| 1421 const Class& field_class = Class::Handle(Z, func.Owner()); | 1367 const Class& field_class = Class::Handle(Z, func.Owner()); |
| 1422 const Field& field = | 1368 const Field& field = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1447 // and handle errors while evaluating the expression. | 1393 // and handle errors while evaluating the expression. |
| 1448 current_block_->statements->Add(new (Z) | 1394 current_block_->statements->Add(new (Z) |
| 1449 InitStaticFieldNode(ident_pos, field)); | 1395 InitStaticFieldNode(ident_pos, field)); |
| 1450 ReturnNode* return_node = | 1396 ReturnNode* return_node = |
| 1451 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); | 1397 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); |
| 1452 current_block_->statements->Add(return_node); | 1398 current_block_->statements->Add(return_node); |
| 1453 } | 1399 } |
| 1454 return CloseBlock(); | 1400 return CloseBlock(); |
| 1455 } | 1401 } |
| 1456 | 1402 |
| 1457 | |
| 1458 // Create AstNodes for an implicit instance getter method: | 1403 // Create AstNodes for an implicit instance getter method: |
| 1459 // LoadLocalNode 0 ('this'); | 1404 // LoadLocalNode 0 ('this'); |
| 1460 // LoadInstanceFieldNode (field_name); | 1405 // LoadInstanceFieldNode (field_name); |
| 1461 // ReturnNode (field's value); | 1406 // ReturnNode (field's value); |
| 1462 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1407 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1463 TRACE_PARSER("ParseInstanceGetter"); | 1408 TRACE_PARSER("ParseInstanceGetter"); |
| 1464 ParamList params; | 1409 ParamList params; |
| 1465 // func.token_pos() points to the name of the field. | 1410 // func.token_pos() points to the name of the field. |
| 1466 const TokenPosition ident_pos = func.token_pos(); | 1411 const TokenPosition ident_pos = func.token_pos(); |
| 1467 ASSERT(current_class().raw() == func.Owner()); | 1412 ASSERT(current_class().raw() == func.Owner()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1486 ASSERT(!field.IsNull()); | 1431 ASSERT(!field.IsNull()); |
| 1487 | 1432 |
| 1488 LoadInstanceFieldNode* load_field = | 1433 LoadInstanceFieldNode* load_field = |
| 1489 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1434 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1490 | 1435 |
| 1491 ReturnNode* return_node = new ReturnNode(ST(ident_pos), load_field); | 1436 ReturnNode* return_node = new ReturnNode(ST(ident_pos), load_field); |
| 1492 current_block_->statements->Add(return_node); | 1437 current_block_->statements->Add(return_node); |
| 1493 return CloseBlock(); | 1438 return CloseBlock(); |
| 1494 } | 1439 } |
| 1495 | 1440 |
| 1496 | |
| 1497 // Create AstNodes for an implicit instance setter method: | 1441 // Create AstNodes for an implicit instance setter method: |
| 1498 // LoadLocalNode 0 ('this') | 1442 // LoadLocalNode 0 ('this') |
| 1499 // LoadLocalNode 1 ('value') | 1443 // LoadLocalNode 1 ('value') |
| 1500 // SetInstanceField (field_name); | 1444 // SetInstanceField (field_name); |
| 1501 // ReturnNode (void); | 1445 // ReturnNode (void); |
| 1502 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1446 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
| 1503 TRACE_PARSER("ParseInstanceSetter"); | 1447 TRACE_PARSER("ParseInstanceSetter"); |
| 1504 // func.token_pos() points to the name of the field. | 1448 // func.token_pos() points to the name of the field. |
| 1505 const TokenPosition ident_pos = func.token_pos(); | 1449 const TokenPosition ident_pos = func.token_pos(); |
| 1506 const String& field_name = *CurrentLiteral(); | 1450 const String& field_name = *CurrentLiteral(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1528 | 1472 |
| 1529 EnsureExpressionTemp(); | 1473 EnsureExpressionTemp(); |
| 1530 StoreInstanceFieldNode* store_field = | 1474 StoreInstanceFieldNode* store_field = |
| 1531 new StoreInstanceFieldNode(ident_pos, receiver, field, value, | 1475 new StoreInstanceFieldNode(ident_pos, receiver, field, value, |
| 1532 /* is_initializer = */ false); | 1476 /* is_initializer = */ false); |
| 1533 current_block_->statements->Add(store_field); | 1477 current_block_->statements->Add(store_field); |
| 1534 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); | 1478 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); |
| 1535 return CloseBlock(); | 1479 return CloseBlock(); |
| 1536 } | 1480 } |
| 1537 | 1481 |
| 1538 | |
| 1539 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1482 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
| 1540 TRACE_PARSER("ParseConstructorClosure"); | 1483 TRACE_PARSER("ParseConstructorClosure"); |
| 1541 const TokenPosition token_pos = func.token_pos(); | 1484 const TokenPosition token_pos = func.token_pos(); |
| 1542 | 1485 |
| 1543 Function& constructor = Function::ZoneHandle(Z); | 1486 Function& constructor = Function::ZoneHandle(Z); |
| 1544 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1487 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
| 1545 ParseConstructorClosurization(&constructor, &type_args); | 1488 ParseConstructorClosurization(&constructor, &type_args); |
| 1546 ASSERT(!constructor.IsNull()); | 1489 ASSERT(!constructor.IsNull()); |
| 1547 | 1490 |
| 1548 ParamList params; | 1491 ParamList params; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 ctor_args->set_names(arg_names); | 1524 ctor_args->set_names(arg_names); |
| 1582 } | 1525 } |
| 1583 | 1526 |
| 1584 AstNode* new_object = | 1527 AstNode* new_object = |
| 1585 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); | 1528 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); |
| 1586 ReturnNode* return_node = new ReturnNode(token_pos, new_object); | 1529 ReturnNode* return_node = new ReturnNode(token_pos, new_object); |
| 1587 current_block_->statements->Add(return_node); | 1530 current_block_->statements->Add(return_node); |
| 1588 return CloseBlock(); | 1531 return CloseBlock(); |
| 1589 } | 1532 } |
| 1590 | 1533 |
| 1591 | |
| 1592 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { | 1534 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { |
| 1593 TRACE_PARSER("ParseImplicitClosure"); | 1535 TRACE_PARSER("ParseImplicitClosure"); |
| 1594 TokenPosition token_pos = func.token_pos(); | 1536 TokenPosition token_pos = func.token_pos(); |
| 1595 | 1537 |
| 1596 OpenFunctionBlock(func); | 1538 OpenFunctionBlock(func); |
| 1597 | 1539 |
| 1598 const Function& parent = Function::Handle(func.parent_function()); | 1540 const Function& parent = Function::Handle(func.parent_function()); |
| 1599 intptr_t type_args_len = 0; // Length of type args vector passed to parent. | 1541 intptr_t type_args_len = 0; // Length of type args vector passed to parent. |
| 1600 LocalVariable* type_args_var = NULL; | 1542 LocalVariable* type_args_var = NULL; |
| 1601 if (FLAG_reify_generic_functions) { | 1543 if (FLAG_reify_generic_functions) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 InvocationMirror::kStatic, im_type, | 1670 InvocationMirror::kStatic, im_type, |
| 1729 NULL); // No existing function. | 1671 NULL); // No existing function. |
| 1730 } | 1672 } |
| 1731 | 1673 |
| 1732 ASSERT(call != NULL); | 1674 ASSERT(call != NULL); |
| 1733 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1675 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1734 current_block_->statements->Add(return_node); | 1676 current_block_->statements->Add(return_node); |
| 1735 return CloseBlock(); | 1677 return CloseBlock(); |
| 1736 } | 1678 } |
| 1737 | 1679 |
| 1738 | |
| 1739 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1680 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1740 TRACE_PARSER("ParseMethodExtractor"); | 1681 TRACE_PARSER("ParseMethodExtractor"); |
| 1741 | 1682 |
| 1742 ParamList params; | 1683 ParamList params; |
| 1743 | 1684 |
| 1744 const TokenPosition ident_pos = func.token_pos(); | 1685 const TokenPosition ident_pos = func.token_pos(); |
| 1745 ASSERT(func.token_pos() == TokenPosition::kMethodExtractor); | 1686 ASSERT(func.token_pos() == TokenPosition::kMethodExtractor); |
| 1746 ASSERT(current_class().raw() == func.Owner()); | 1687 ASSERT(current_class().raw() == func.Owner()); |
| 1747 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1688 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1748 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1689 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
| 1749 ASSERT(!func.HasOptionalParameters()); | 1690 ASSERT(!func.HasOptionalParameters()); |
| 1750 | 1691 |
| 1751 // Build local scope for function and populate with the formal parameters. | 1692 // Build local scope for function and populate with the formal parameters. |
| 1752 OpenFunctionBlock(func); | 1693 OpenFunctionBlock(func); |
| 1753 AddFormalParamsToScope(¶ms, current_block_->scope); | 1694 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1754 | 1695 |
| 1755 // Receiver is local 0. | 1696 // Receiver is local 0. |
| 1756 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1697 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1757 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1698 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1758 | 1699 |
| 1759 ClosureNode* closure = new ClosureNode( | 1700 ClosureNode* closure = new ClosureNode( |
| 1760 ident_pos, Function::ZoneHandle(Z, func.extracted_method_closure()), | 1701 ident_pos, Function::ZoneHandle(Z, func.extracted_method_closure()), |
| 1761 load_receiver, NULL); | 1702 load_receiver, NULL); |
| 1762 | 1703 |
| 1763 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1704 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
| 1764 current_block_->statements->Add(return_node); | 1705 current_block_->statements->Add(return_node); |
| 1765 return CloseBlock(); | 1706 return CloseBlock(); |
| 1766 } | 1707 } |
| 1767 | 1708 |
| 1768 | |
| 1769 void Parser::BuildDispatcherScope(const Function& func, | 1709 void Parser::BuildDispatcherScope(const Function& func, |
| 1770 const ArgumentsDescriptor& desc) { | 1710 const ArgumentsDescriptor& desc) { |
| 1771 ParamList params; | 1711 ParamList params; |
| 1772 // Receiver first. | 1712 // Receiver first. |
| 1773 TokenPosition token_pos = func.token_pos(); | 1713 TokenPosition token_pos = func.token_pos(); |
| 1774 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1714 params.AddReceiver(ReceiverType(current_class()), token_pos); |
| 1775 // Remaining positional parameters. | 1715 // Remaining positional parameters. |
| 1776 intptr_t i = 1; | 1716 intptr_t i = 1; |
| 1777 for (; i < desc.PositionalCount(); ++i) { | 1717 for (; i < desc.PositionalCount(); ++i) { |
| 1778 ParamDesc p; | 1718 ParamDesc p; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1809 // Insert function type arguments variable to scope. | 1749 // Insert function type arguments variable to scope. |
| 1810 LocalVariable* type_args_var = new (Z) LocalVariable( | 1750 LocalVariable* type_args_var = new (Z) LocalVariable( |
| 1811 TokenPosition::kNoSource, TokenPosition::kNoSource, | 1751 TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 1812 Symbols::FunctionTypeArgumentsVar(), Object::dynamic_type()); | 1752 Symbols::FunctionTypeArgumentsVar(), Object::dynamic_type()); |
| 1813 current_block_->scope->AddVariable(type_args_var); | 1753 current_block_->scope->AddVariable(type_args_var); |
| 1814 ASSERT(FunctionLevel() == 0); | 1754 ASSERT(FunctionLevel() == 0); |
| 1815 parsed_function_->set_function_type_arguments(type_args_var); | 1755 parsed_function_->set_function_type_arguments(type_args_var); |
| 1816 } | 1756 } |
| 1817 } | 1757 } |
| 1818 | 1758 |
| 1819 | |
| 1820 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { | 1759 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { |
| 1821 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1760 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
| 1822 ASSERT(FLAG_lazy_dispatchers); | 1761 ASSERT(FLAG_lazy_dispatchers); |
| 1823 ASSERT(func.IsNoSuchMethodDispatcher()); | 1762 ASSERT(func.IsNoSuchMethodDispatcher()); |
| 1824 TokenPosition token_pos = func.token_pos(); | 1763 TokenPosition token_pos = func.token_pos(); |
| 1825 ASSERT(func.token_pos() == TokenPosition::kMinSource); | 1764 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
| 1826 ASSERT(current_class().raw() == func.Owner()); | 1765 ASSERT(current_class().raw() == func.Owner()); |
| 1827 | 1766 |
| 1828 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); | 1767 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); |
| 1829 ASSERT(desc.Count() > 0); | 1768 ASSERT(desc.Count() > 0); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1867 Symbols::NoSuchMethod(), args_desc); | 1806 Symbols::NoSuchMethod(), args_desc); |
| 1868 } | 1807 } |
| 1869 StaticCallNode* call = | 1808 StaticCallNode* call = |
| 1870 new StaticCallNode(token_pos, no_such_method, arguments); | 1809 new StaticCallNode(token_pos, no_such_method, arguments); |
| 1871 | 1810 |
| 1872 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1811 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1873 current_block_->statements->Add(return_node); | 1812 current_block_->statements->Add(return_node); |
| 1874 return CloseBlock(); | 1813 return CloseBlock(); |
| 1875 } | 1814 } |
| 1876 | 1815 |
| 1877 | |
| 1878 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { | 1816 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
| 1879 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1817 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
| 1880 ASSERT(func.IsInvokeFieldDispatcher()); | 1818 ASSERT(func.IsInvokeFieldDispatcher()); |
| 1881 TokenPosition token_pos = func.token_pos(); | 1819 TokenPosition token_pos = func.token_pos(); |
| 1882 ASSERT(func.token_pos() == TokenPosition::kMinSource); | 1820 ASSERT(func.token_pos() == TokenPosition::kMinSource); |
| 1883 ASSERT(current_class().raw() == func.Owner()); | 1821 ASSERT(current_class().raw() == func.Owner()); |
| 1884 | 1822 |
| 1885 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); | 1823 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
| 1886 ArgumentsDescriptor desc(args_desc); | 1824 ArgumentsDescriptor desc(args_desc); |
| 1887 ASSERT(desc.Count() > 0); | 1825 ASSERT(desc.Count() > 0); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 result = new ClosureCallNode(token_pos, function_object, args); | 1873 result = new ClosureCallNode(token_pos, function_object, args); |
| 1936 } else { | 1874 } else { |
| 1937 result = BuildClosureCall(token_pos, function_object, args); | 1875 result = BuildClosureCall(token_pos, function_object, args); |
| 1938 } | 1876 } |
| 1939 | 1877 |
| 1940 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1878 ReturnNode* return_node = new ReturnNode(token_pos, result); |
| 1941 current_block_->statements->Add(return_node); | 1879 current_block_->statements->Add(return_node); |
| 1942 return CloseBlock(); | 1880 return CloseBlock(); |
| 1943 } | 1881 } |
| 1944 | 1882 |
| 1945 | |
| 1946 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, | 1883 AstNode* Parser::BuildClosureCall(TokenPosition token_pos, |
| 1947 AstNode* closure, | 1884 AstNode* closure, |
| 1948 ArgumentListNode* arguments) { | 1885 ArgumentListNode* arguments) { |
| 1949 return new InstanceCallNode(token_pos, closure, Symbols::Call(), arguments); | 1886 return new InstanceCallNode(token_pos, closure, Symbols::Call(), arguments); |
| 1950 } | 1887 } |
| 1951 | 1888 |
| 1952 | |
| 1953 void Parser::SkipToMatching() { | 1889 void Parser::SkipToMatching() { |
| 1954 Token::Kind opening_token = CurrentToken(); | 1890 Token::Kind opening_token = CurrentToken(); |
| 1955 ASSERT((opening_token == Token::kLBRACE) || | 1891 ASSERT((opening_token == Token::kLBRACE) || |
| 1956 (opening_token == Token::kLPAREN)); | 1892 (opening_token == Token::kLPAREN)); |
| 1957 GrowableArray<Token::Kind> token_stack(8); | 1893 GrowableArray<Token::Kind> token_stack(8); |
| 1958 GrowableArray<TokenPosition> token_pos_stack(8); | 1894 GrowableArray<TokenPosition> token_pos_stack(8); |
| 1959 // Adding the first opening brace here, because it will be consumed | 1895 // Adding the first opening brace here, because it will be consumed |
| 1960 // in the loop right away. | 1896 // in the loop right away. |
| 1961 token_stack.Add(opening_token); | 1897 token_stack.Add(opening_token); |
| 1962 const TokenPosition start_pos = TokenPos(); | 1898 const TokenPosition start_pos = TokenPos(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2007 Error::Handle(), script_, opening_pos, Report::AtLocation, | 1943 Error::Handle(), script_, opening_pos, Report::AtLocation, |
| 2008 Report::kWarning, allocation_space_, "unbalanced '%s' opens here", | 1944 Report::kWarning, allocation_space_, "unbalanced '%s' opens here", |
| 2009 Token::Str(opening_token))); | 1945 Token::Str(opening_token))); |
| 2010 ReportErrors(error, script_, token_pos, "unbalanced '%s'", | 1946 ReportErrors(error, script_, token_pos, "unbalanced '%s'", |
| 2011 Token::Str(token)); | 1947 Token::Str(token)); |
| 2012 } else if (unexpected_token_found) { | 1948 } else if (unexpected_token_found) { |
| 2013 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); | 1949 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token)); |
| 2014 } | 1950 } |
| 2015 } | 1951 } |
| 2016 | 1952 |
| 2017 | |
| 2018 void Parser::SkipBlock() { | 1953 void Parser::SkipBlock() { |
| 2019 ASSERT(CurrentToken() == Token::kLBRACE); | 1954 ASSERT(CurrentToken() == Token::kLBRACE); |
| 2020 SkipToMatching(); | 1955 SkipToMatching(); |
| 2021 } | 1956 } |
| 2022 | 1957 |
| 2023 | |
| 2024 // Skips tokens up to and including matching closing parenthesis. | 1958 // Skips tokens up to and including matching closing parenthesis. |
| 2025 void Parser::SkipToMatchingParenthesis() { | 1959 void Parser::SkipToMatchingParenthesis() { |
| 2026 ASSERT(CurrentToken() == Token::kLPAREN); | 1960 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2027 SkipToMatching(); | 1961 SkipToMatching(); |
| 2028 ASSERT(CurrentToken() == Token::kRPAREN); | 1962 ASSERT(CurrentToken() == Token::kRPAREN); |
| 2029 ConsumeToken(); | 1963 ConsumeToken(); |
| 2030 } | 1964 } |
| 2031 | 1965 |
| 2032 | |
| 2033 // Parses a parameter type as defined by the 'parameterTypeList' production. | 1966 // Parses a parameter type as defined by the 'parameterTypeList' production. |
| 2034 void Parser::ParseParameterType(ParamList* params) { | 1967 void Parser::ParseParameterType(ParamList* params) { |
| 2035 TRACE_PARSER("ParseParameterType"); | 1968 TRACE_PARSER("ParseParameterType"); |
| 2036 ParamDesc parameter; | 1969 ParamDesc parameter; |
| 2037 | 1970 |
| 2038 parameter.has_explicit_type = true; // The type is required by the syntax. | 1971 parameter.has_explicit_type = true; // The type is required by the syntax. |
| 2039 // It is too early to resolve the type here, since it can be a result type | 1972 // It is too early to resolve the type here, since it can be a result type |
| 2040 // referring to a not yet declared function type parameter. | 1973 // referring to a not yet declared function type parameter. |
| 2041 parameter.type = &AbstractType::ZoneHandle( | 1974 parameter.type = &AbstractType::ZoneHandle( |
| 2042 Z, ParseTypeOrFunctionType(false, ClassFinalizer::kDoNotResolve)); | 1975 Z, ParseTypeOrFunctionType(false, ClassFinalizer::kDoNotResolve)); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2093 } | 2026 } |
| 2094 if (params->implicitly_final) { | 2027 if (params->implicitly_final) { |
| 2095 parameter.is_final = true; | 2028 parameter.is_final = true; |
| 2096 } | 2029 } |
| 2097 params->parameters->Add(parameter); | 2030 params->parameters->Add(parameter); |
| 2098 if (parameter.is_covariant) { | 2031 if (parameter.is_covariant) { |
| 2099 params->has_covariant = true; | 2032 params->has_covariant = true; |
| 2100 } | 2033 } |
| 2101 } | 2034 } |
| 2102 | 2035 |
| 2103 | |
| 2104 // Parses a formal parameter as defined by the 'formalParameterList' production. | 2036 // Parses a formal parameter as defined by the 'formalParameterList' production. |
| 2105 void Parser::ParseFormalParameter(bool allow_explicit_default_value, | 2037 void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
| 2106 bool evaluate_metadata, | 2038 bool evaluate_metadata, |
| 2107 ParamList* params) { | 2039 ParamList* params) { |
| 2108 TRACE_PARSER("ParseFormalParameter"); | 2040 TRACE_PARSER("ParseFormalParameter"); |
| 2109 ParamDesc parameter; | 2041 ParamDesc parameter; |
| 2110 bool var_seen = false; | 2042 bool var_seen = false; |
| 2111 bool final_seen = false; | 2043 bool final_seen = false; |
| 2112 bool this_seen = false; | 2044 bool this_seen = false; |
| 2113 | 2045 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 } | 2256 } |
| 2325 if (params->implicitly_final) { | 2257 if (params->implicitly_final) { |
| 2326 parameter.is_final = true; | 2258 parameter.is_final = true; |
| 2327 } | 2259 } |
| 2328 params->parameters->Add(parameter); | 2260 params->parameters->Add(parameter); |
| 2329 if (parameter.is_covariant) { | 2261 if (parameter.is_covariant) { |
| 2330 params->has_covariant = true; | 2262 params->has_covariant = true; |
| 2331 } | 2263 } |
| 2332 } | 2264 } |
| 2333 | 2265 |
| 2334 | |
| 2335 // Parses a sequence of normal or optional formal parameters. | 2266 // Parses a sequence of normal or optional formal parameters. |
| 2336 void Parser::ParseFormalParameters(bool use_function_type_syntax, | 2267 void Parser::ParseFormalParameters(bool use_function_type_syntax, |
| 2337 bool allow_explicit_default_values, | 2268 bool allow_explicit_default_values, |
| 2338 bool evaluate_metadata, | 2269 bool evaluate_metadata, |
| 2339 ParamList* params) { | 2270 ParamList* params) { |
| 2340 TRACE_PARSER("ParseFormalParameters"); | 2271 TRACE_PARSER("ParseFormalParameters"); |
| 2341 // Optional parameter lists cannot be empty. | 2272 // Optional parameter lists cannot be empty. |
| 2342 // The completely empty parameter list is handled before getting here. | 2273 // The completely empty parameter list is handled before getting here. |
| 2343 bool has_seen_parameter = false; | 2274 bool has_seen_parameter = false; |
| 2344 do { | 2275 do { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2370 ASSERT(!allow_explicit_default_values && !evaluate_metadata); | 2301 ASSERT(!allow_explicit_default_values && !evaluate_metadata); |
| 2371 ParseParameterType(params); | 2302 ParseParameterType(params); |
| 2372 } else { | 2303 } else { |
| 2373 ParseFormalParameter(allow_explicit_default_values, evaluate_metadata, | 2304 ParseFormalParameter(allow_explicit_default_values, evaluate_metadata, |
| 2374 params); | 2305 params); |
| 2375 } | 2306 } |
| 2376 has_seen_parameter = true; | 2307 has_seen_parameter = true; |
| 2377 } while (CurrentToken() == Token::kCOMMA); | 2308 } while (CurrentToken() == Token::kCOMMA); |
| 2378 } | 2309 } |
| 2379 | 2310 |
| 2380 | |
| 2381 void Parser::ParseFormalParameterList(bool use_function_type_syntax, | 2311 void Parser::ParseFormalParameterList(bool use_function_type_syntax, |
| 2382 bool allow_explicit_default_values, | 2312 bool allow_explicit_default_values, |
| 2383 bool evaluate_metadata, | 2313 bool evaluate_metadata, |
| 2384 ParamList* params) { | 2314 ParamList* params) { |
| 2385 TRACE_PARSER("ParseFormalParameterList"); | 2315 TRACE_PARSER("ParseFormalParameterList"); |
| 2386 ASSERT(CurrentToken() == Token::kLPAREN); | 2316 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2387 | 2317 |
| 2388 if (LookaheadToken(1) != Token::kRPAREN) { | 2318 if (LookaheadToken(1) != Token::kRPAREN) { |
| 2389 // Parse fixed parameters. | 2319 // Parse fixed parameters. |
| 2390 ParseFormalParameters(use_function_type_syntax, | 2320 ParseFormalParameters(use_function_type_syntax, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2407 !params->has_optional_positional_parameters && | 2337 !params->has_optional_positional_parameters && |
| 2408 !params->has_optional_named_parameters) { | 2338 !params->has_optional_named_parameters) { |
| 2409 ReportError("',' or ')' expected"); | 2339 ReportError("',' or ')' expected"); |
| 2410 } | 2340 } |
| 2411 } else { | 2341 } else { |
| 2412 ConsumeToken(); | 2342 ConsumeToken(); |
| 2413 } | 2343 } |
| 2414 ExpectToken(Token::kRPAREN); | 2344 ExpectToken(Token::kRPAREN); |
| 2415 } | 2345 } |
| 2416 | 2346 |
| 2417 | |
| 2418 String& Parser::ParseNativeDeclaration() { | 2347 String& Parser::ParseNativeDeclaration() { |
| 2419 TRACE_PARSER("ParseNativeDeclaration"); | 2348 TRACE_PARSER("ParseNativeDeclaration"); |
| 2420 ASSERT(IsSymbol(Symbols::Native())); | 2349 ASSERT(IsSymbol(Symbols::Native())); |
| 2421 ConsumeToken(); | 2350 ConsumeToken(); |
| 2422 CheckToken(Token::kSTRING, "string literal expected"); | 2351 CheckToken(Token::kSTRING, "string literal expected"); |
| 2423 String& native_name = *CurrentLiteral(); | 2352 String& native_name = *CurrentLiteral(); |
| 2424 ConsumeToken(); | 2353 ConsumeToken(); |
| 2425 return native_name; | 2354 return native_name; |
| 2426 } | 2355 } |
| 2427 | 2356 |
| 2428 | |
| 2429 // Resolve and return the dynamic function of the given name in the superclass. | 2357 // Resolve and return the dynamic function of the given name in the superclass. |
| 2430 // If it is not found, and resolve_getter is true, try to resolve a getter of | 2358 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 2431 // the same name. If it is still not found, return noSuchMethod and | 2359 // the same name. If it is still not found, return noSuchMethod and |
| 2432 // set is_no_such_method to true.. | 2360 // set is_no_such_method to true.. |
| 2433 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, | 2361 RawFunction* Parser::GetSuperFunction(TokenPosition token_pos, |
| 2434 const String& name, | 2362 const String& name, |
| 2435 ArgumentListNode* arguments, | 2363 ArgumentListNode* arguments, |
| 2436 bool resolve_getter, | 2364 bool resolve_getter, |
| 2437 bool* is_no_such_method) { | 2365 bool* is_no_such_method) { |
| 2438 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); | 2366 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2460 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, | 2388 super_func = Resolver::ResolveDynamicAnyArgs(Z, super_class, |
| 2461 Symbols::NoSuchMethod()); | 2389 Symbols::NoSuchMethod()); |
| 2462 ASSERT(!super_func.IsNull()); | 2390 ASSERT(!super_func.IsNull()); |
| 2463 *is_no_such_method = true; | 2391 *is_no_such_method = true; |
| 2464 } else { | 2392 } else { |
| 2465 *is_no_such_method = false; | 2393 *is_no_such_method = false; |
| 2466 } | 2394 } |
| 2467 return super_func.raw(); | 2395 return super_func.raw(); |
| 2468 } | 2396 } |
| 2469 | 2397 |
| 2470 | |
| 2471 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 2398 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
| 2472 TokenPosition call_pos, | 2399 TokenPosition call_pos, |
| 2473 const String& function_name, | 2400 const String& function_name, |
| 2474 const ArgumentListNode& function_args, | 2401 const ArgumentListNode& function_args, |
| 2475 const LocalVariable* temp_for_last_arg, | 2402 const LocalVariable* temp_for_last_arg, |
| 2476 bool is_super_invocation) { | 2403 bool is_super_invocation) { |
| 2477 const TokenPosition args_pos = function_args.token_pos(); | 2404 const TokenPosition args_pos = function_args.token_pos(); |
| 2478 // Build arguments to the call to the static | 2405 // Build arguments to the call to the static |
| 2479 // InvocationMirror._allocateInvocationMirror method. | 2406 // InvocationMirror._allocateInvocationMirror method. |
| 2480 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2407 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2514 const Class& mirror_class = | 2441 const Class& mirror_class = |
| 2515 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); | 2442 Class::Handle(Library::LookupCoreClass(Symbols::InvocationMirror())); |
| 2516 ASSERT(!mirror_class.IsNull()); | 2443 ASSERT(!mirror_class.IsNull()); |
| 2517 const Function& allocation_function = | 2444 const Function& allocation_function = |
| 2518 Function::ZoneHandle(mirror_class.LookupStaticFunction( | 2445 Function::ZoneHandle(mirror_class.LookupStaticFunction( |
| 2519 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 2446 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
| 2520 ASSERT(!allocation_function.IsNull()); | 2447 ASSERT(!allocation_function.IsNull()); |
| 2521 return new StaticCallNode(call_pos, allocation_function, arguments); | 2448 return new StaticCallNode(call_pos, allocation_function, arguments); |
| 2522 } | 2449 } |
| 2523 | 2450 |
| 2524 | |
| 2525 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 2451 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
| 2526 TokenPosition call_pos, | 2452 TokenPosition call_pos, |
| 2527 const String& function_name, | 2453 const String& function_name, |
| 2528 const ArgumentListNode& function_args, | 2454 const ArgumentListNode& function_args, |
| 2529 const LocalVariable* temp_for_last_arg, | 2455 const LocalVariable* temp_for_last_arg, |
| 2530 bool is_super_invocation) { | 2456 bool is_super_invocation) { |
| 2531 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 2457 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
| 2532 const TokenPosition args_pos = function_args.token_pos(); | 2458 const TokenPosition args_pos = function_args.token_pos(); |
| 2533 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2459 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 2534 arguments->Add(function_args.NodeAt(0)); | 2460 arguments->Add(function_args.NodeAt(0)); |
| 2535 // The second argument is the invocation mirror. | 2461 // The second argument is the invocation mirror. |
| 2536 arguments->Add( | 2462 arguments->Add( |
| 2537 BuildInvocationMirrorAllocation(call_pos, function_name, function_args, | 2463 BuildInvocationMirrorAllocation(call_pos, function_name, function_args, |
| 2538 temp_for_last_arg, is_super_invocation)); | 2464 temp_for_last_arg, is_super_invocation)); |
| 2539 return arguments; | 2465 return arguments; |
| 2540 } | 2466 } |
| 2541 | 2467 |
| 2542 | |
| 2543 AstNode* Parser::ParseSuperCall(const String& function_name, | 2468 AstNode* Parser::ParseSuperCall(const String& function_name, |
| 2544 const TypeArguments& func_type_args) { | 2469 const TypeArguments& func_type_args) { |
| 2545 TRACE_PARSER("ParseSuperCall"); | 2470 TRACE_PARSER("ParseSuperCall"); |
| 2546 ASSERT(CurrentToken() == Token::kLPAREN); | 2471 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2547 const TokenPosition supercall_pos = TokenPos(); | 2472 const TokenPosition supercall_pos = TokenPos(); |
| 2548 | 2473 |
| 2549 // 'this' parameter is the first argument to super call (after the type args). | 2474 // 'this' parameter is the first argument to super call (after the type args). |
| 2550 ArgumentListNode* arguments = | 2475 ArgumentListNode* arguments = |
| 2551 new ArgumentListNode(supercall_pos, func_type_args); | 2476 new ArgumentListNode(supercall_pos, func_type_args); |
| 2552 AstNode* receiver = LoadReceiver(supercall_pos); | 2477 AstNode* receiver = LoadReceiver(supercall_pos); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2572 } | 2497 } |
| 2573 return BuildClosureCall(supercall_pos, closure, closure_arguments); | 2498 return BuildClosureCall(supercall_pos, closure, closure_arguments); |
| 2574 } | 2499 } |
| 2575 if (is_no_such_method) { | 2500 if (is_no_such_method) { |
| 2576 arguments = BuildNoSuchMethodArguments(supercall_pos, function_name, | 2501 arguments = BuildNoSuchMethodArguments(supercall_pos, function_name, |
| 2577 *arguments, NULL, true); | 2502 *arguments, NULL, true); |
| 2578 } | 2503 } |
| 2579 return new StaticCallNode(supercall_pos, super_function, arguments); | 2504 return new StaticCallNode(supercall_pos, super_function, arguments); |
| 2580 } | 2505 } |
| 2581 | 2506 |
| 2582 | |
| 2583 // Simple test if a node is side effect free. | 2507 // Simple test if a node is side effect free. |
| 2584 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 2508 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
| 2585 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 2509 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
| 2586 } | 2510 } |
| 2587 | 2511 |
| 2588 | |
| 2589 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 2512 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
| 2590 ASSERT(super->IsSuper()); | 2513 ASSERT(super->IsSuper()); |
| 2591 AstNode* super_op = NULL; | 2514 AstNode* super_op = NULL; |
| 2592 const TokenPosition super_pos = super->token_pos(); | 2515 const TokenPosition super_pos = super->token_pos(); |
| 2593 if ((op == Token::kNEGATE) || (op == Token::kBIT_NOT)) { | 2516 if ((op == Token::kNEGATE) || (op == Token::kBIT_NOT)) { |
| 2594 // Resolve the operator function in the superclass. | 2517 // Resolve the operator function in the superclass. |
| 2595 const String& operator_function_name = Symbols::Token(op); | 2518 const String& operator_function_name = Symbols::Token(op); |
| 2596 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 2519 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
| 2597 AstNode* receiver = LoadReceiver(super_pos); | 2520 AstNode* receiver = LoadReceiver(super_pos); |
| 2598 op_arguments->Add(receiver); | 2521 op_arguments->Add(receiver); |
| 2599 const bool kResolveGetter = false; | 2522 const bool kResolveGetter = false; |
| 2600 bool is_no_such_method = false; | 2523 bool is_no_such_method = false; |
| 2601 const Function& super_operator = Function::ZoneHandle( | 2524 const Function& super_operator = Function::ZoneHandle( |
| 2602 Z, GetSuperFunction(super_pos, operator_function_name, op_arguments, | 2525 Z, GetSuperFunction(super_pos, operator_function_name, op_arguments, |
| 2603 kResolveGetter, &is_no_such_method)); | 2526 kResolveGetter, &is_no_such_method)); |
| 2604 if (is_no_such_method) { | 2527 if (is_no_such_method) { |
| 2605 op_arguments = BuildNoSuchMethodArguments( | 2528 op_arguments = BuildNoSuchMethodArguments( |
| 2606 super_pos, operator_function_name, *op_arguments, NULL, true); | 2529 super_pos, operator_function_name, *op_arguments, NULL, true); |
| 2607 } | 2530 } |
| 2608 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 2531 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
| 2609 } else { | 2532 } else { |
| 2610 ReportError(super_pos, "illegal super operator call"); | 2533 ReportError(super_pos, "illegal super operator call"); |
| 2611 } | 2534 } |
| 2612 return super_op; | 2535 return super_op; |
| 2613 } | 2536 } |
| 2614 | 2537 |
| 2615 | |
| 2616 AstNode* Parser::ParseSuperOperator() { | 2538 AstNode* Parser::ParseSuperOperator() { |
| 2617 TRACE_PARSER("ParseSuperOperator"); | 2539 TRACE_PARSER("ParseSuperOperator"); |
| 2618 AstNode* super_op = NULL; | 2540 AstNode* super_op = NULL; |
| 2619 const TokenPosition operator_pos = TokenPos(); | 2541 const TokenPosition operator_pos = TokenPos(); |
| 2620 | 2542 |
| 2621 if (CurrentToken() == Token::kLBRACK) { | 2543 if (CurrentToken() == Token::kLBRACK) { |
| 2622 ConsumeToken(); | 2544 ConsumeToken(); |
| 2623 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2545 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2624 ExpectToken(Token::kRBRACK); | 2546 ExpectToken(Token::kRBRACK); |
| 2625 AstNode* receiver = LoadReceiver(operator_pos); | 2547 AstNode* receiver = LoadReceiver(operator_pos); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2660 operator_pos, operator_function_name, *op_arguments, NULL, true); | 2582 operator_pos, operator_function_name, *op_arguments, NULL, true); |
| 2661 } | 2583 } |
| 2662 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2584 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| 2663 if (negate_result) { | 2585 if (negate_result) { |
| 2664 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2586 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
| 2665 } | 2587 } |
| 2666 } | 2588 } |
| 2667 return super_op; | 2589 return super_op; |
| 2668 } | 2590 } |
| 2669 | 2591 |
| 2670 | |
| 2671 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2592 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
| 2672 TokenPosition token_pos, | 2593 TokenPosition token_pos, |
| 2673 AstNode* receiver) { | 2594 AstNode* receiver) { |
| 2674 Function& implicit_closure_function = | 2595 Function& implicit_closure_function = |
| 2675 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); | 2596 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); |
| 2676 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2597 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 2677 } | 2598 } |
| 2678 | 2599 |
| 2679 | |
| 2680 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2600 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
| 2681 TokenPosition field_pos) { | 2601 TokenPosition field_pos) { |
| 2682 TRACE_PARSER("ParseSuperFieldAccess"); | 2602 TRACE_PARSER("ParseSuperFieldAccess"); |
| 2683 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); | 2603 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); |
| 2684 if (super_class.IsNull()) { | 2604 if (super_class.IsNull()) { |
| 2685 ReportError("class '%s' does not have a superclass", | 2605 ReportError("class '%s' does not have a superclass", |
| 2686 String::Handle(Z, current_class().Name()).ToCString()); | 2606 String::Handle(Z, current_class().Name()).ToCString()); |
| 2687 } | 2607 } |
| 2688 AstNode* implicit_argument = LoadReceiver(field_pos); | 2608 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 2689 | 2609 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2715 implicit_argument); | 2635 implicit_argument); |
| 2716 } | 2636 } |
| 2717 // No function or field exists of the specified field_name. | 2637 // No function or field exists of the specified field_name. |
| 2718 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2638 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
| 2719 } | 2639 } |
| 2720 } | 2640 } |
| 2721 return new (Z) | 2641 return new (Z) |
| 2722 StaticGetterNode(field_pos, implicit_argument, super_class, field_name); | 2642 StaticGetterNode(field_pos, implicit_argument, super_class, field_name); |
| 2723 } | 2643 } |
| 2724 | 2644 |
| 2725 | |
| 2726 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2645 StaticCallNode* Parser::GenerateSuperConstructorCall( |
| 2727 const Class& cls, | 2646 const Class& cls, |
| 2728 TokenPosition supercall_pos, | 2647 TokenPosition supercall_pos, |
| 2729 LocalVariable* receiver, | 2648 LocalVariable* receiver, |
| 2730 ArgumentListNode* forwarding_args) { | 2649 ArgumentListNode* forwarding_args) { |
| 2731 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2650 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2732 // Omit the implicit super() if there is no super class (i.e. | 2651 // Omit the implicit super() if there is no super class (i.e. |
| 2733 // we're not compiling class Object), or if the super class is an | 2652 // we're not compiling class Object), or if the super class is an |
| 2734 // artificially generated "wrapper class" that has no constructor. | 2653 // artificially generated "wrapper class" that has no constructor. |
| 2735 if (super_class.IsNull() || | 2654 if (super_class.IsNull() || |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2785 arguments->length(), arguments->names(), | 2704 arguments->length(), arguments->names(), |
| 2786 &error_message)) { | 2705 &error_message)) { |
| 2787 ReportError(supercall_pos, | 2706 ReportError(supercall_pos, |
| 2788 "invalid arguments passed to super constructor '%s()': %s", | 2707 "invalid arguments passed to super constructor '%s()': %s", |
| 2789 String::Handle(Z, super_class.Name()).ToCString(), | 2708 String::Handle(Z, super_class.Name()).ToCString(), |
| 2790 error_message.ToCString()); | 2709 error_message.ToCString()); |
| 2791 } | 2710 } |
| 2792 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2711 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2793 } | 2712 } |
| 2794 | 2713 |
| 2795 | |
| 2796 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, | 2714 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, |
| 2797 LocalVariable* receiver) { | 2715 LocalVariable* receiver) { |
| 2798 TRACE_PARSER("ParseSuperInitializer"); | 2716 TRACE_PARSER("ParseSuperInitializer"); |
| 2799 ASSERT(CurrentToken() == Token::kSUPER); | 2717 ASSERT(CurrentToken() == Token::kSUPER); |
| 2800 const TokenPosition supercall_pos = TokenPos(); | 2718 const TokenPosition supercall_pos = TokenPos(); |
| 2801 ConsumeToken(); | 2719 ConsumeToken(); |
| 2802 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2720 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2803 ASSERT(!super_class.IsNull()); | 2721 ASSERT(!super_class.IsNull()); |
| 2804 String& ctor_name = String::Handle(Z, super_class.Name()); | 2722 String& ctor_name = String::Handle(Z, super_class.Name()); |
| 2805 ctor_name = Symbols::FromConcat(T, ctor_name, Symbols::Dot()); | 2723 ctor_name = Symbols::FromConcat(T, ctor_name, Symbols::Dot()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2840 if (!super_ctor.AreValidArguments(arguments->type_args_len(), | 2758 if (!super_ctor.AreValidArguments(arguments->type_args_len(), |
| 2841 arguments->length(), arguments->names(), | 2759 arguments->length(), arguments->names(), |
| 2842 &error_message)) { | 2760 &error_message)) { |
| 2843 ReportError(supercall_pos, | 2761 ReportError(supercall_pos, |
| 2844 "invalid arguments passed to super class constructor '%s': %s", | 2762 "invalid arguments passed to super class constructor '%s': %s", |
| 2845 ctor_name.ToCString(), error_message.ToCString()); | 2763 ctor_name.ToCString(), error_message.ToCString()); |
| 2846 } | 2764 } |
| 2847 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2765 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2848 } | 2766 } |
| 2849 | 2767 |
| 2850 | |
| 2851 AstNode* Parser::ParseInitializer(const Class& cls, | 2768 AstNode* Parser::ParseInitializer(const Class& cls, |
| 2852 LocalVariable* receiver, | 2769 LocalVariable* receiver, |
| 2853 GrowableArray<Field*>* initialized_fields) { | 2770 GrowableArray<Field*>* initialized_fields) { |
| 2854 TRACE_PARSER("ParseInitializer"); | 2771 TRACE_PARSER("ParseInitializer"); |
| 2855 const TokenPosition field_pos = TokenPos(); | 2772 const TokenPosition field_pos = TokenPos(); |
| 2856 if (FLAG_assert_initializer && CurrentToken() == Token::kASSERT) { | 2773 if (FLAG_assert_initializer && CurrentToken() == Token::kASSERT) { |
| 2857 return ParseAssertStatement(current_function().is_const()); | 2774 return ParseAssertStatement(current_function().is_const()); |
| 2858 } | 2775 } |
| 2859 if (CurrentToken() == Token::kTHIS) { | 2776 if (CurrentToken() == Token::kTHIS) { |
| 2860 ConsumeToken(); | 2777 ConsumeToken(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 AstNode* initializer = CheckDuplicateFieldInit(field_pos, initialized_fields, | 2811 AstNode* initializer = CheckDuplicateFieldInit(field_pos, initialized_fields, |
| 2895 instance, &field, init_expr); | 2812 instance, &field, init_expr); |
| 2896 if (initializer == NULL) { | 2813 if (initializer == NULL) { |
| 2897 initializer = | 2814 initializer = |
| 2898 new (Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr, | 2815 new (Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr, |
| 2899 /* is_initializer = */ true); | 2816 /* is_initializer = */ true); |
| 2900 } | 2817 } |
| 2901 return initializer; | 2818 return initializer; |
| 2902 } | 2819 } |
| 2903 | 2820 |
| 2904 | |
| 2905 void Parser::CheckFieldsInitialized(const Class& cls) { | 2821 void Parser::CheckFieldsInitialized(const Class& cls) { |
| 2906 const Array& fields = Array::Handle(Z, cls.fields()); | 2822 const Array& fields = Array::Handle(Z, cls.fields()); |
| 2907 Field& field = Field::Handle(Z); | 2823 Field& field = Field::Handle(Z); |
| 2908 SequenceNode* initializers = current_block_->statements; | 2824 SequenceNode* initializers = current_block_->statements; |
| 2909 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 2825 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
| 2910 field ^= fields.At(field_num); | 2826 field ^= fields.At(field_num); |
| 2911 if (field.is_static()) { | 2827 if (field.is_static()) { |
| 2912 continue; | 2828 continue; |
| 2913 } | 2829 } |
| 2914 | 2830 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2925 } | 2841 } |
| 2926 } | 2842 } |
| 2927 } | 2843 } |
| 2928 | 2844 |
| 2929 if (found) continue; | 2845 if (found) continue; |
| 2930 | 2846 |
| 2931 field.RecordStore(Object::null_object()); | 2847 field.RecordStore(Object::null_object()); |
| 2932 } | 2848 } |
| 2933 } | 2849 } |
| 2934 | 2850 |
| 2935 | |
| 2936 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2851 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
| 2937 // Only use this function if the initialized field originates | 2852 // Only use this function if the initialized field originates |
| 2938 // from a different class. We need to save and restore the | 2853 // from a different class. We need to save and restore the |
| 2939 // library and token stream (script). | 2854 // library and token stream (script). |
| 2940 // The current_class remains unchanged, so that type arguments | 2855 // The current_class remains unchanged, so that type arguments |
| 2941 // are resolved in the correct scope class. | 2856 // are resolved in the correct scope class. |
| 2942 ASSERT(current_class().raw() != field.Origin()); | 2857 ASSERT(current_class().raw() != field.Origin()); |
| 2943 const Library& saved_library = Library::Handle(Z, library().raw()); | 2858 const Library& saved_library = Library::Handle(Z, library().raw()); |
| 2944 const Script& saved_script = Script::Handle(Z, script().raw()); | 2859 const Script& saved_script = Script::Handle(Z, script().raw()); |
| 2945 const TokenPosition saved_token_pos = TokenPos(); | 2860 const TokenPosition saved_token_pos = TokenPos(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2959 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2874 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2960 if (init_expr->EvalConstExpr() != NULL) { | 2875 if (init_expr->EvalConstExpr() != NULL) { |
| 2961 init_expr = FoldConstExpr(expr_pos, init_expr); | 2876 init_expr = FoldConstExpr(expr_pos, init_expr); |
| 2962 } | 2877 } |
| 2963 } | 2878 } |
| 2964 set_library(saved_library); | 2879 set_library(saved_library); |
| 2965 SetScript(saved_script, saved_token_pos); | 2880 SetScript(saved_script, saved_token_pos); |
| 2966 return init_expr; | 2881 return init_expr; |
| 2967 } | 2882 } |
| 2968 | 2883 |
| 2969 | |
| 2970 void Parser::ParseInitializedInstanceFields( | 2884 void Parser::ParseInitializedInstanceFields( |
| 2971 const Class& cls, | 2885 const Class& cls, |
| 2972 LocalVariable* receiver, | 2886 LocalVariable* receiver, |
| 2973 GrowableArray<Field*>* initialized_fields) { | 2887 GrowableArray<Field*>* initialized_fields) { |
| 2974 TRACE_PARSER("ParseInitializedInstanceFields"); | 2888 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 2975 const Array& fields = Array::Handle(Z, cls.fields()); | 2889 const Array& fields = Array::Handle(Z, cls.fields()); |
| 2976 Field& f = Field::Handle(Z); | 2890 Field& f = Field::Handle(Z); |
| 2977 const TokenPosition saved_pos = TokenPos(); | 2891 const TokenPosition saved_pos = TokenPos(); |
| 2978 for (int i = 0; i < fields.Length(); i++) { | 2892 for (int i = 0; i < fields.Length(); i++) { |
| 2979 f ^= fields.At(i); | 2893 f ^= fields.At(i); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3012 AstNode* field_init = new StoreInstanceFieldNode( | 2926 AstNode* field_init = new StoreInstanceFieldNode( |
| 3013 field.token_pos(), instance, field, init_expr, | 2927 field.token_pos(), instance, field, init_expr, |
| 3014 /* is_initializer = */ true); | 2928 /* is_initializer = */ true); |
| 3015 current_block_->statements->Add(field_init); | 2929 current_block_->statements->Add(field_init); |
| 3016 } | 2930 } |
| 3017 } | 2931 } |
| 3018 initialized_fields->Add(NULL); // End of inline initializers. | 2932 initialized_fields->Add(NULL); // End of inline initializers. |
| 3019 SetPosition(saved_pos); | 2933 SetPosition(saved_pos); |
| 3020 } | 2934 } |
| 3021 | 2935 |
| 3022 | |
| 3023 AstNode* Parser::CheckDuplicateFieldInit( | 2936 AstNode* Parser::CheckDuplicateFieldInit( |
| 3024 TokenPosition init_pos, | 2937 TokenPosition init_pos, |
| 3025 GrowableArray<Field*>* initialized_fields, | 2938 GrowableArray<Field*>* initialized_fields, |
| 3026 AstNode* instance, | 2939 AstNode* instance, |
| 3027 Field* field, | 2940 Field* field, |
| 3028 AstNode* init_value) { | 2941 AstNode* init_value) { |
| 3029 ASSERT(!field->is_static()); | 2942 ASSERT(!field->is_static()); |
| 3030 AstNode* result = NULL; | 2943 AstNode* result = NULL; |
| 3031 const String& field_name = String::Handle(field->name()); | 2944 const String& field_name = String::Handle(field->name()); |
| 3032 String& initialized_name = String::Handle(Z); | 2945 String& initialized_name = String::Handle(Z); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3115 initializer_idx++; | 3028 initializer_idx++; |
| 3116 if (initialized_field->raw() == field->raw()) { | 3029 if (initialized_field->raw() == field->raw()) { |
| 3117 ReportError(init_pos, "duplicate initializer for field %s", | 3030 ReportError(init_pos, "duplicate initializer for field %s", |
| 3118 String::Handle(Z, field->name()).ToCString()); | 3031 String::Handle(Z, field->name()).ToCString()); |
| 3119 } | 3032 } |
| 3120 } | 3033 } |
| 3121 initialized_fields->Add(field); | 3034 initialized_fields->Add(field); |
| 3122 return result; | 3035 return result; |
| 3123 } | 3036 } |
| 3124 | 3037 |
| 3125 | |
| 3126 void Parser::ParseInitializers(const Class& cls, | 3038 void Parser::ParseInitializers(const Class& cls, |
| 3127 LocalVariable* receiver, | 3039 LocalVariable* receiver, |
| 3128 GrowableArray<Field*>* initialized_fields) { | 3040 GrowableArray<Field*>* initialized_fields) { |
| 3129 TRACE_PARSER("ParseInitializers"); | 3041 TRACE_PARSER("ParseInitializers"); |
| 3130 bool super_init_is_last = false; | 3042 bool super_init_is_last = false; |
| 3131 intptr_t super_init_index = -1; | 3043 intptr_t super_init_index = -1; |
| 3132 StaticCallNode* super_init_call = NULL; | 3044 StaticCallNode* super_init_call = NULL; |
| 3133 if (CurrentToken() == Token::kCOLON) { | 3045 if (CurrentToken() == Token::kCOLON) { |
| 3134 do { | 3046 do { |
| 3135 ConsumeToken(); // Colon or comma. | 3047 ConsumeToken(); // Colon or comma. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3187 AstNode* save_temp = new (Z) StoreLocalNode(arg->token_pos(), temp, arg); | 3099 AstNode* save_temp = new (Z) StoreLocalNode(arg->token_pos(), temp, arg); |
| 3188 saved_args->AddNode(save_temp); | 3100 saved_args->AddNode(save_temp); |
| 3189 ctor_args->SetNodeAt(i, new (Z) LoadLocalNode(arg->token_pos(), temp)); | 3101 ctor_args->SetNodeAt(i, new (Z) LoadLocalNode(arg->token_pos(), temp)); |
| 3190 } | 3102 } |
| 3191 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); | 3103 current_block_->statements->ReplaceNodeAt(super_init_index, saved_args); |
| 3192 current_block_->statements->Add(super_init_call); | 3104 current_block_->statements->Add(super_init_call); |
| 3193 } | 3105 } |
| 3194 CheckFieldsInitialized(cls); | 3106 CheckFieldsInitialized(cls); |
| 3195 } | 3107 } |
| 3196 | 3108 |
| 3197 | |
| 3198 void Parser::ParseConstructorRedirection(const Class& cls, | 3109 void Parser::ParseConstructorRedirection(const Class& cls, |
| 3199 LocalVariable* receiver) { | 3110 LocalVariable* receiver) { |
| 3200 TRACE_PARSER("ParseConstructorRedirection"); | 3111 TRACE_PARSER("ParseConstructorRedirection"); |
| 3201 ExpectToken(Token::kCOLON); | 3112 ExpectToken(Token::kCOLON); |
| 3202 ASSERT(CurrentToken() == Token::kTHIS); | 3113 ASSERT(CurrentToken() == Token::kTHIS); |
| 3203 const TokenPosition call_pos = TokenPos(); | 3114 const TokenPosition call_pos = TokenPos(); |
| 3204 ConsumeToken(); | 3115 ConsumeToken(); |
| 3205 String& ctor_name = String::Handle(Z, cls.Name()); | 3116 String& ctor_name = String::Handle(Z, cls.Name()); |
| 3206 GrowableHandlePtrArray<const String> pieces(Z, 3); | 3117 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 3207 pieces.Add(ctor_name); | 3118 pieces.Add(ctor_name); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3242 arguments->length(), arguments->names(), | 3153 arguments->length(), arguments->names(), |
| 3243 &error_message)) { | 3154 &error_message)) { |
| 3244 ReportError(call_pos, "invalid arguments passed to constructor '%s': %s", | 3155 ReportError(call_pos, "invalid arguments passed to constructor '%s': %s", |
| 3245 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString(), | 3156 String::Handle(Z, redirect_ctor.UserVisibleName()).ToCString(), |
| 3246 error_message.ToCString()); | 3157 error_message.ToCString()); |
| 3247 } | 3158 } |
| 3248 current_block_->statements->Add( | 3159 current_block_->statements->Add( |
| 3249 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 3160 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 3250 } | 3161 } |
| 3251 | 3162 |
| 3252 | |
| 3253 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 3163 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 3254 ASSERT(func.IsGenerativeConstructor()); | 3164 ASSERT(func.IsGenerativeConstructor()); |
| 3255 ASSERT(func.Owner() == current_class().raw()); | 3165 ASSERT(func.Owner() == current_class().raw()); |
| 3256 const TokenPosition ctor_pos = TokenPos(); | 3166 const TokenPosition ctor_pos = TokenPos(); |
| 3257 OpenFunctionBlock(func); | 3167 OpenFunctionBlock(func); |
| 3258 | 3168 |
| 3259 LocalVariable* receiver = | 3169 LocalVariable* receiver = |
| 3260 new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 3170 new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 3261 Symbols::This(), *ReceiverType(current_class())); | 3171 Symbols::This(), *ReceiverType(current_class())); |
| 3262 current_block_->scope->InsertParameterAt(0, receiver); | 3172 current_block_->scope->InsertParameterAt(0, receiver); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 current_block_->statements->Add(super_call); | 3228 current_block_->statements->Add(super_call); |
| 3319 } | 3229 } |
| 3320 CheckFieldsInitialized(current_class()); | 3230 CheckFieldsInitialized(current_class()); |
| 3321 | 3231 |
| 3322 // Empty constructor body. | 3232 // Empty constructor body. |
| 3323 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); | 3233 current_block_->statements->Add(new ReturnNode(ST(ctor_pos))); |
| 3324 SequenceNode* statements = CloseBlock(); | 3234 SequenceNode* statements = CloseBlock(); |
| 3325 return statements; | 3235 return statements; |
| 3326 } | 3236 } |
| 3327 | 3237 |
| 3328 | |
| 3329 // Returns a zone allocated string. | 3238 // Returns a zone allocated string. |
| 3330 static char* DumpPendingFunctions( | 3239 static char* DumpPendingFunctions( |
| 3331 Zone* zone, | 3240 Zone* zone, |
| 3332 const GrowableObjectArray& pending_functions) { | 3241 const GrowableObjectArray& pending_functions) { |
| 3333 ASSERT(zone != NULL); | 3242 ASSERT(zone != NULL); |
| 3334 char* result = OS::SCreate(zone, "Pending Functions:\n"); | 3243 char* result = OS::SCreate(zone, "Pending Functions:\n"); |
| 3335 for (intptr_t i = 0; i < pending_functions.Length(); i++) { | 3244 for (intptr_t i = 0; i < pending_functions.Length(); i++) { |
| 3336 const Function& func = | 3245 const Function& func = |
| 3337 Function::Handle(zone, Function::RawCast(pending_functions.At(i))); | 3246 Function::Handle(zone, Function::RawCast(pending_functions.At(i))); |
| 3338 const String& fname = String::Handle(zone, func.UserVisibleName()); | 3247 const String& fname = String::Handle(zone, func.UserVisibleName()); |
| 3339 result = OS::SCreate(zone, "%s%" Pd ": %s\n", result, i, fname.ToCString()); | 3248 result = OS::SCreate(zone, "%s%" Pd ": %s\n", result, i, fname.ToCString()); |
| 3340 } | 3249 } |
| 3341 return result; | 3250 return result; |
| 3342 } | 3251 } |
| 3343 | 3252 |
| 3344 | |
| 3345 void Parser::CheckRecursiveInvocation() { | 3253 void Parser::CheckRecursiveInvocation() { |
| 3346 const GrowableObjectArray& pending_functions = | 3254 const GrowableObjectArray& pending_functions = |
| 3347 GrowableObjectArray::Handle(Z, T->pending_functions()); | 3255 GrowableObjectArray::Handle(Z, T->pending_functions()); |
| 3348 ASSERT(!pending_functions.IsNull()); | 3256 ASSERT(!pending_functions.IsNull()); |
| 3349 for (int i = 0; i < pending_functions.Length(); i++) { | 3257 for (int i = 0; i < pending_functions.Length(); i++) { |
| 3350 if (pending_functions.At(i) == current_function().raw()) { | 3258 if (pending_functions.At(i) == current_function().raw()) { |
| 3351 const String& fname = | 3259 const String& fname = |
| 3352 String::Handle(Z, current_function().UserVisibleName()); | 3260 String::Handle(Z, current_function().UserVisibleName()); |
| 3353 if (FLAG_trace_service) { | 3261 if (FLAG_trace_service) { |
| 3354 const char* pending_function_dump = | 3262 const char* pending_function_dump = |
| 3355 DumpPendingFunctions(Z, pending_functions); | 3263 DumpPendingFunctions(Z, pending_functions); |
| 3356 ASSERT(pending_function_dump != NULL); | 3264 ASSERT(pending_function_dump != NULL); |
| 3357 ReportError("circular dependency for function %s\n%s", | 3265 ReportError("circular dependency for function %s\n%s", |
| 3358 fname.ToCString(), pending_function_dump); | 3266 fname.ToCString(), pending_function_dump); |
| 3359 } else { | 3267 } else { |
| 3360 ReportError("circular dependency for function %s", fname.ToCString()); | 3268 ReportError("circular dependency for function %s", fname.ToCString()); |
| 3361 } | 3269 } |
| 3362 } | 3270 } |
| 3363 } | 3271 } |
| 3364 ASSERT(!unregister_pending_function_); | 3272 ASSERT(!unregister_pending_function_); |
| 3365 pending_functions.Add(current_function(), Heap::kOld); | 3273 pending_functions.Add(current_function(), Heap::kOld); |
| 3366 unregister_pending_function_ = true; | 3274 unregister_pending_function_ = true; |
| 3367 } | 3275 } |
| 3368 | 3276 |
| 3369 | |
| 3370 // Parser is at the opening parenthesis of the formal parameter declaration | 3277 // Parser is at the opening parenthesis of the formal parameter declaration |
| 3371 // of function. Parse the formal parameters, initializers and code. | 3278 // of function. Parse the formal parameters, initializers and code. |
| 3372 SequenceNode* Parser::ParseConstructor(const Function& func) { | 3279 SequenceNode* Parser::ParseConstructor(const Function& func) { |
| 3373 TRACE_PARSER("ParseConstructor"); | 3280 TRACE_PARSER("ParseConstructor"); |
| 3374 ASSERT(func.IsGenerativeConstructor()); | 3281 ASSERT(func.IsGenerativeConstructor()); |
| 3375 ASSERT(!func.IsFactory()); | 3282 ASSERT(!func.IsFactory()); |
| 3376 ASSERT(!func.is_static()); | 3283 ASSERT(!func.is_static()); |
| 3377 ASSERT(!func.IsLocalFunction()); | 3284 ASSERT(!func.IsLocalFunction()); |
| 3378 const Class& cls = Class::Handle(Z, func.Owner()); | 3285 const Class& cls = Class::Handle(Z, func.Owner()); |
| 3379 ASSERT(!cls.IsNull()); | 3286 ASSERT(!cls.IsNull()); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3534 | 3441 |
| 3535 SequenceNode* ctor_block = CloseBlock(); | 3442 SequenceNode* ctor_block = CloseBlock(); |
| 3536 if (ctor_block->length() > 0) { | 3443 if (ctor_block->length() > 0) { |
| 3537 current_block_->statements->Add(ctor_block); | 3444 current_block_->statements->Add(ctor_block); |
| 3538 } | 3445 } |
| 3539 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 3446 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
| 3540 SequenceNode* statements = CloseBlock(); | 3447 SequenceNode* statements = CloseBlock(); |
| 3541 return statements; | 3448 return statements; |
| 3542 } | 3449 } |
| 3543 | 3450 |
| 3544 | |
| 3545 // Parser is at the opening parenthesis of the formal parameter | 3451 // Parser is at the opening parenthesis of the formal parameter |
| 3546 // declaration of the function or constructor. | 3452 // declaration of the function or constructor. |
| 3547 // Parse the formal parameters and code. | 3453 // Parse the formal parameters and code. |
| 3548 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { | 3454 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { |
| 3549 TRACE_PARSER("ParseFunc"); | 3455 TRACE_PARSER("ParseFunc"); |
| 3550 ASSERT(innermost_function().raw() == func.raw()); | 3456 ASSERT(innermost_function().raw() == func.raw()); |
| 3551 | 3457 |
| 3552 // Save current try index. Try index starts at zero for each function. | 3458 // Save current try index. Try index starts at zero for each function. |
| 3553 intptr_t saved_try_index = last_used_try_index_; | 3459 intptr_t saved_try_index = last_used_try_index_; |
| 3554 last_used_try_index_ = 0; | 3460 last_used_try_index_ = 0; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3838 } else if (func.IsAsyncGenClosure()) { | 3744 } else if (func.IsAsyncGenClosure()) { |
| 3839 body = CloseAsyncGeneratorClosure(body); | 3745 body = CloseAsyncGeneratorClosure(body); |
| 3840 } | 3746 } |
| 3841 EnsureHasReturnStatement(body, end_token_pos); | 3747 EnsureHasReturnStatement(body, end_token_pos); |
| 3842 current_block_->statements->Add(body); | 3748 current_block_->statements->Add(body); |
| 3843 last_used_try_index_ = saved_try_index; | 3749 last_used_try_index_ = saved_try_index; |
| 3844 async_temp_scope_ = saved_async_temp_scope; | 3750 async_temp_scope_ = saved_async_temp_scope; |
| 3845 return CloseBlock(); | 3751 return CloseBlock(); |
| 3846 } | 3752 } |
| 3847 | 3753 |
| 3848 | |
| 3849 void Parser::AddEqualityNullCheck() { | 3754 void Parser::AddEqualityNullCheck() { |
| 3850 AstNode* argument = new LoadLocalNode( | 3755 AstNode* argument = new LoadLocalNode( |
| 3851 TokenPosition::kNoSource, current_block_->scope->parent()->VariableAt(1)); | 3756 TokenPosition::kNoSource, current_block_->scope->parent()->VariableAt(1)); |
| 3852 LiteralNode* null_operand = | 3757 LiteralNode* null_operand = |
| 3853 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); | 3758 new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z)); |
| 3854 ComparisonNode* check_arg = new ComparisonNode( | 3759 ComparisonNode* check_arg = new ComparisonNode( |
| 3855 TokenPosition::kNoSource, Token::kEQ_STRICT, argument, null_operand); | 3760 TokenPosition::kNoSource, Token::kEQ_STRICT, argument, null_operand); |
| 3856 ComparisonNode* result = | 3761 ComparisonNode* result = |
| 3857 new ComparisonNode(TokenPosition::kNoSource, Token::kEQ_STRICT, | 3762 new ComparisonNode(TokenPosition::kNoSource, Token::kEQ_STRICT, |
| 3858 LoadReceiver(TokenPosition::kNoSource), null_operand); | 3763 LoadReceiver(TokenPosition::kNoSource), null_operand); |
| 3859 SequenceNode* arg_is_null = | 3764 SequenceNode* arg_is_null = |
| 3860 new SequenceNode(TokenPosition::kNoSource, current_block_->scope); | 3765 new SequenceNode(TokenPosition::kNoSource, current_block_->scope); |
| 3861 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); | 3766 arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result)); |
| 3862 IfNode* if_arg_null = | 3767 IfNode* if_arg_null = |
| 3863 new IfNode(TokenPosition::kNoSource, check_arg, arg_is_null, NULL); | 3768 new IfNode(TokenPosition::kNoSource, check_arg, arg_is_null, NULL); |
| 3864 current_block_->statements->Add(if_arg_null); | 3769 current_block_->statements->Add(if_arg_null); |
| 3865 } | 3770 } |
| 3866 | 3771 |
| 3867 | |
| 3868 void Parser::SkipIf(Token::Kind token) { | 3772 void Parser::SkipIf(Token::Kind token) { |
| 3869 if (CurrentToken() == token) { | 3773 if (CurrentToken() == token) { |
| 3870 ConsumeToken(); | 3774 ConsumeToken(); |
| 3871 } | 3775 } |
| 3872 } | 3776 } |
| 3873 | 3777 |
| 3874 | |
| 3875 void Parser::SkipInitializers() { | 3778 void Parser::SkipInitializers() { |
| 3876 ASSERT(CurrentToken() == Token::kCOLON); | 3779 ASSERT(CurrentToken() == Token::kCOLON); |
| 3877 do { | 3780 do { |
| 3878 ConsumeToken(); // Colon or comma. | 3781 ConsumeToken(); // Colon or comma. |
| 3879 if (CurrentToken() == Token::kSUPER) { | 3782 if (CurrentToken() == Token::kSUPER) { |
| 3880 ConsumeToken(); | 3783 ConsumeToken(); |
| 3881 if (CurrentToken() == Token::kPERIOD) { | 3784 if (CurrentToken() == Token::kPERIOD) { |
| 3882 ConsumeToken(); | 3785 ConsumeToken(); |
| 3883 ExpectIdentifier("identifier expected"); | 3786 ExpectIdentifier("identifier expected"); |
| 3884 } | 3787 } |
| 3885 CheckToken(Token::kLPAREN); | 3788 CheckToken(Token::kLPAREN); |
| 3886 SkipToMatchingParenthesis(); | 3789 SkipToMatchingParenthesis(); |
| 3887 } else if (FLAG_assert_initializer && (CurrentToken() == Token::kASSERT)) { | 3790 } else if (FLAG_assert_initializer && (CurrentToken() == Token::kASSERT)) { |
| 3888 ConsumeToken(); | 3791 ConsumeToken(); |
| 3889 CheckToken(Token::kLPAREN); | 3792 CheckToken(Token::kLPAREN); |
| 3890 SkipToMatchingParenthesis(); | 3793 SkipToMatchingParenthesis(); |
| 3891 } else { | 3794 } else { |
| 3892 SkipIf(Token::kTHIS); | 3795 SkipIf(Token::kTHIS); |
| 3893 SkipIf(Token::kPERIOD); | 3796 SkipIf(Token::kPERIOD); |
| 3894 ExpectIdentifier("identifier expected"); | 3797 ExpectIdentifier("identifier expected"); |
| 3895 ExpectToken(Token::kASSIGN); | 3798 ExpectToken(Token::kASSIGN); |
| 3896 SetAllowFunctionLiterals(false); | 3799 SetAllowFunctionLiterals(false); |
| 3897 SkipExpr(); | 3800 SkipExpr(); |
| 3898 SetAllowFunctionLiterals(true); | 3801 SetAllowFunctionLiterals(true); |
| 3899 } | 3802 } |
| 3900 } while (CurrentToken() == Token::kCOMMA); | 3803 } while (CurrentToken() == Token::kCOMMA); |
| 3901 } | 3804 } |
| 3902 | 3805 |
| 3903 | |
| 3904 // If the current identifier is a library prefix followed by a period, | 3806 // If the current identifier is a library prefix followed by a period, |
| 3905 // consume the identifier and period, and return the resolved library | 3807 // consume the identifier and period, and return the resolved library |
| 3906 // prefix. | 3808 // prefix. |
| 3907 RawLibraryPrefix* Parser::ParsePrefix() { | 3809 RawLibraryPrefix* Parser::ParsePrefix() { |
| 3908 ASSERT(IsIdentifier()); | 3810 ASSERT(IsIdentifier()); |
| 3909 // A library prefix can never stand by itself. It must be followed by | 3811 // A library prefix can never stand by itself. It must be followed by |
| 3910 // a period or a hash mark (for closurization). | 3812 // a period or a hash mark (for closurization). |
| 3911 Token::Kind next_token = LookaheadToken(1); | 3813 Token::Kind next_token = LookaheadToken(1); |
| 3912 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) { | 3814 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) { |
| 3913 return LibraryPrefix::null(); | 3815 return LibraryPrefix::null(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3940 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { | 3842 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { |
| 3941 return LibraryPrefix::null(); | 3843 return LibraryPrefix::null(); |
| 3942 } | 3844 } |
| 3943 | 3845 |
| 3944 // We have a name that is not shadowed, followed by a period or #. | 3846 // We have a name that is not shadowed, followed by a period or #. |
| 3945 // Consume the identifier, let the caller consume the . or #. | 3847 // Consume the identifier, let the caller consume the . or #. |
| 3946 ConsumeToken(); | 3848 ConsumeToken(); |
| 3947 return prefix.raw(); | 3849 return prefix.raw(); |
| 3948 } | 3850 } |
| 3949 | 3851 |
| 3950 | |
| 3951 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3852 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 3952 TRACE_PARSER("ParseMethodOrConstructor"); | 3853 TRACE_PARSER("ParseMethodOrConstructor"); |
| 3953 // We are at the beginning of the formal parameters list. | 3854 // We are at the beginning of the formal parameters list. |
| 3954 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || | 3855 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || |
| 3955 method->IsGetter()); | 3856 method->IsGetter()); |
| 3956 ASSERT(method->type != NULL); // May still be unresolved. | 3857 ASSERT(method->type != NULL); // May still be unresolved. |
| 3957 ASSERT(current_member_ == method); | 3858 ASSERT(current_member_ == method); |
| 3958 | 3859 |
| 3959 if (method->has_covariant) { | 3860 if (method->has_covariant) { |
| 3960 ReportError(method->name_pos, | 3861 ReportError(method->name_pos, |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4302 } | 4203 } |
| 4303 | 4204 |
| 4304 ASSERT(is_top_level_); | 4205 ASSERT(is_top_level_); |
| 4305 AddFormalParamsToFunction(&method->params, func); | 4206 AddFormalParamsToFunction(&method->params, func); |
| 4306 ASSERT(innermost_function().raw() == func.raw()); | 4207 ASSERT(innermost_function().raw() == func.raw()); |
| 4307 innermost_function_ = Function::null(); | 4208 innermost_function_ = Function::null(); |
| 4308 ResolveSignature(func); | 4209 ResolveSignature(func); |
| 4309 members->AddFunction(func); | 4210 members->AddFunction(func); |
| 4310 } | 4211 } |
| 4311 | 4212 |
| 4312 | |
| 4313 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 4213 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
| 4314 TRACE_PARSER("ParseFieldDefinition"); | 4214 TRACE_PARSER("ParseFieldDefinition"); |
| 4315 // The parser has read the first field name and is now at the token | 4215 // The parser has read the first field name and is now at the token |
| 4316 // after the field name. | 4216 // after the field name. |
| 4317 ASSERT(CurrentToken() == Token::kSEMICOLON || | 4217 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 4318 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); | 4218 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); |
| 4319 ASSERT(field->type != NULL); | 4219 ASSERT(field->type != NULL); |
| 4320 ASSERT(field->name_pos.IsReal()); | 4220 ASSERT(field->name_pos.IsReal()); |
| 4321 ASSERT(current_member_ == field); | 4221 ASSERT(current_member_ == field); |
| 4322 // All const fields are also final. | 4222 // All const fields are also final. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4475 if (CurrentToken() != Token::kCOMMA) { | 4375 if (CurrentToken() != Token::kCOMMA) { |
| 4476 break; | 4376 break; |
| 4477 } | 4377 } |
| 4478 ConsumeToken(); | 4378 ConsumeToken(); |
| 4479 field->name_pos = this->TokenPos(); | 4379 field->name_pos = this->TokenPos(); |
| 4480 field->name = ExpectIdentifier("field name expected"); | 4380 field->name = ExpectIdentifier("field name expected"); |
| 4481 } | 4381 } |
| 4482 ExpectSemicolon(); | 4382 ExpectSemicolon(); |
| 4483 } | 4383 } |
| 4484 | 4384 |
| 4485 | |
| 4486 void Parser::CheckOperatorArity(const MemberDesc& member) { | 4385 void Parser::CheckOperatorArity(const MemberDesc& member) { |
| 4487 intptr_t expected_num_parameters; // Includes receiver. | 4386 intptr_t expected_num_parameters; // Includes receiver. |
| 4488 Token::Kind op = member.operator_token; | 4387 Token::Kind op = member.operator_token; |
| 4489 if (op == Token::kASSIGN_INDEX) { | 4388 if (op == Token::kASSIGN_INDEX) { |
| 4490 expected_num_parameters = 3; | 4389 expected_num_parameters = 3; |
| 4491 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) { | 4390 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) { |
| 4492 expected_num_parameters = 1; | 4391 expected_num_parameters = 1; |
| 4493 } else { | 4392 } else { |
| 4494 expected_num_parameters = 2; | 4393 expected_num_parameters = 2; |
| 4495 } | 4394 } |
| 4496 if ((member.params.num_optional_parameters > 0) || | 4395 if ((member.params.num_optional_parameters > 0) || |
| 4497 member.params.has_optional_positional_parameters || | 4396 member.params.has_optional_positional_parameters || |
| 4498 member.params.has_optional_named_parameters || | 4397 member.params.has_optional_named_parameters || |
| 4499 (member.params.num_fixed_parameters != expected_num_parameters)) { | 4398 (member.params.num_fixed_parameters != expected_num_parameters)) { |
| 4500 // Subtract receiver when reporting number of expected arguments. | 4399 // Subtract receiver when reporting number of expected arguments. |
| 4501 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", | 4400 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", |
| 4502 member.name->ToCString(), (expected_num_parameters - 1)); | 4401 member.name->ToCString(), (expected_num_parameters - 1)); |
| 4503 } | 4402 } |
| 4504 } | 4403 } |
| 4505 | 4404 |
| 4506 | |
| 4507 void Parser::CheckMemberNameConflict(ClassDesc* members, MemberDesc* member) { | 4405 void Parser::CheckMemberNameConflict(ClassDesc* members, MemberDesc* member) { |
| 4508 const String& name = *member->DictName(); | 4406 const String& name = *member->DictName(); |
| 4509 if (name.Equals(members->class_name())) { | 4407 if (name.Equals(members->class_name())) { |
| 4510 ReportError(member->name_pos, "%s '%s' conflicts with class name", | 4408 ReportError(member->name_pos, "%s '%s' conflicts with class name", |
| 4511 member->ToCString(), name.ToCString()); | 4409 member->ToCString(), name.ToCString()); |
| 4512 } | 4410 } |
| 4513 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { | 4411 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { |
| 4514 ReportError(member->name_pos, "%s '%s' conflicts with type parameter", | 4412 ReportError(member->name_pos, "%s '%s' conflicts with type parameter", |
| 4515 member->ToCString(), name.ToCString()); | 4413 member->ToCString(), name.ToCString()); |
| 4516 } | 4414 } |
| 4517 for (int i = 0; i < members->members().length(); i++) { | 4415 for (int i = 0; i < members->members().length(); i++) { |
| 4518 MemberDesc* existing_member = &members->members()[i]; | 4416 MemberDesc* existing_member = &members->members()[i]; |
| 4519 if (name.Equals(*existing_member->DictName())) { | 4417 if (name.Equals(*existing_member->DictName())) { |
| 4520 ReportError( | 4418 ReportError( |
| 4521 member->name_pos, "%s '%s' conflicts with previously declared %s", | 4419 member->name_pos, "%s '%s' conflicts with previously declared %s", |
| 4522 member->ToCString(), name.ToCString(), existing_member->ToCString()); | 4420 member->ToCString(), name.ToCString(), existing_member->ToCString()); |
| 4523 } | 4421 } |
| 4524 } | 4422 } |
| 4525 } | 4423 } |
| 4526 | 4424 |
| 4527 | |
| 4528 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4425 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 4529 TokenPosition metadata_pos) { | 4426 TokenPosition metadata_pos) { |
| 4530 TRACE_PARSER("ParseClassMemberDefinition"); | 4427 TRACE_PARSER("ParseClassMemberDefinition"); |
| 4531 MemberDesc member; | 4428 MemberDesc member; |
| 4532 current_member_ = &member; | 4429 current_member_ = &member; |
| 4533 member.metadata_pos = metadata_pos; | 4430 member.metadata_pos = metadata_pos; |
| 4534 member.decl_begin_pos = TokenPos(); | 4431 member.decl_begin_pos = TokenPos(); |
| 4535 if ((CurrentToken() == Token::kEXTERNAL) && | 4432 if ((CurrentToken() == Token::kEXTERNAL) && |
| 4536 (LookaheadToken(1) != Token::kLPAREN)) { | 4433 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4537 ConsumeToken(); | 4434 ConsumeToken(); |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4733 } | 4630 } |
| 4734 ParseFieldDefinition(members, &member); | 4631 ParseFieldDefinition(members, &member); |
| 4735 } else { | 4632 } else { |
| 4736 UnexpectedToken(); | 4633 UnexpectedToken(); |
| 4737 } | 4634 } |
| 4738 current_member_ = NULL; | 4635 current_member_ = NULL; |
| 4739 CheckMemberNameConflict(members, &member); | 4636 CheckMemberNameConflict(members, &member); |
| 4740 members->AddMember(member); | 4637 members->AddMember(member); |
| 4741 } | 4638 } |
| 4742 | 4639 |
| 4743 | |
| 4744 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, | 4640 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
| 4745 const Object& tl_owner, | 4641 const Object& tl_owner, |
| 4746 TokenPosition metadata_pos) { | 4642 TokenPosition metadata_pos) { |
| 4747 TRACE_PARSER("ParseEnumDeclaration"); | 4643 TRACE_PARSER("ParseEnumDeclaration"); |
| 4748 const TokenPosition declaration_pos = | 4644 const TokenPosition declaration_pos = |
| 4749 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); | 4645 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); |
| 4750 ConsumeToken(); | 4646 ConsumeToken(); |
| 4751 const TokenPosition name_pos = TokenPos(); | 4647 const TokenPosition name_pos = TokenPos(); |
| 4752 String* enum_name = | 4648 String* enum_name = |
| 4753 ExpectUserDefinedTypeIdentifier("enum type name expected"); | 4649 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4782 library_.AddClass(cls); | 4678 library_.AddClass(cls); |
| 4783 cls.set_is_synthesized_class(); | 4679 cls.set_is_synthesized_class(); |
| 4784 cls.set_is_enum_class(); | 4680 cls.set_is_enum_class(); |
| 4785 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { | 4681 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { |
| 4786 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4682 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
| 4787 } | 4683 } |
| 4788 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); | 4684 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
| 4789 pending_classes.Add(cls, Heap::kOld); | 4685 pending_classes.Add(cls, Heap::kOld); |
| 4790 } | 4686 } |
| 4791 | 4687 |
| 4792 | |
| 4793 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4688 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| 4794 const Object& tl_owner, | 4689 const Object& tl_owner, |
| 4795 TokenPosition metadata_pos) { | 4690 TokenPosition metadata_pos) { |
| 4796 TRACE_PARSER("ParseClassDeclaration"); | 4691 TRACE_PARSER("ParseClassDeclaration"); |
| 4797 bool is_patch = false; | 4692 bool is_patch = false; |
| 4798 bool is_abstract = false; | 4693 bool is_abstract = false; |
| 4799 TokenPosition declaration_pos = | 4694 TokenPosition declaration_pos = |
| 4800 metadata_pos.IsReal() ? metadata_pos : TokenPos(); | 4695 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
| 4801 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 4696 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
| 4802 is_patch = true; | 4697 is_patch = true; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4968 | 4863 |
| 4969 if (is_mixin_declaration) { | 4864 if (is_mixin_declaration) { |
| 4970 ExpectSemicolon(); | 4865 ExpectSemicolon(); |
| 4971 } else { | 4866 } else { |
| 4972 CheckToken(Token::kLBRACE); | 4867 CheckToken(Token::kLBRACE); |
| 4973 SkipBlock(); | 4868 SkipBlock(); |
| 4974 ExpectToken(Token::kRBRACE); | 4869 ExpectToken(Token::kRBRACE); |
| 4975 } | 4870 } |
| 4976 } | 4871 } |
| 4977 | 4872 |
| 4978 | |
| 4979 void Parser::ParseClassDefinition(const Class& cls) { | 4873 void Parser::ParseClassDefinition(const Class& cls) { |
| 4980 TRACE_PARSER("ParseClassDefinition"); | 4874 TRACE_PARSER("ParseClassDefinition"); |
| 4981 INC_STAT(thread(), num_classes_parsed, 1); | 4875 INC_STAT(thread(), num_classes_parsed, 1); |
| 4982 set_current_class(cls); | 4876 set_current_class(cls); |
| 4983 is_top_level_ = true; | 4877 is_top_level_ = true; |
| 4984 String& class_name = String::Handle(Z, cls.Name()); | 4878 String& class_name = String::Handle(Z, cls.Name()); |
| 4985 SkipMetadata(); | 4879 SkipMetadata(); |
| 4986 if (CurrentToken() == Token::kABSTRACT) { | 4880 if (CurrentToken() == Token::kABSTRACT) { |
| 4987 ConsumeToken(); | 4881 ConsumeToken(); |
| 4988 } | 4882 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5036 Report::LongJumpF(error, script_, class_pos, | 4930 Report::LongJumpF(error, script_, class_pos, |
| 5037 "patch validation failed, not applying patch.\n"); | 4931 "patch validation failed, not applying patch.\n"); |
| 5038 } | 4932 } |
| 5039 } | 4933 } |
| 5040 if (!orig_class.ApplyPatch(cls, &error)) { | 4934 if (!orig_class.ApplyPatch(cls, &error)) { |
| 5041 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4935 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
| 5042 } | 4936 } |
| 5043 } | 4937 } |
| 5044 } | 4938 } |
| 5045 | 4939 |
| 5046 | |
| 5047 void Parser::ParseEnumDefinition(const Class& cls) { | 4940 void Parser::ParseEnumDefinition(const Class& cls) { |
| 5048 TRACE_PARSER("ParseEnumDefinition"); | 4941 TRACE_PARSER("ParseEnumDefinition"); |
| 5049 INC_STAT(thread(), num_classes_parsed, 1); | 4942 INC_STAT(thread(), num_classes_parsed, 1); |
| 5050 set_current_class(cls); | 4943 set_current_class(cls); |
| 5051 const Class& helper_class = | 4944 const Class& helper_class = |
| 5052 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); | 4945 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); |
| 5053 ASSERT(!helper_class.IsNull()); | 4946 ASSERT(!helper_class.IsNull()); |
| 5054 | 4947 |
| 5055 SkipMetadata(); | 4948 SkipMetadata(); |
| 5056 ExpectToken(Token::kENUM); | 4949 ExpectToken(Token::kENUM); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5227 Z, helper_class.LookupDynamicFunctionAllowPrivate(Symbols::hashCode())); | 5120 Z, helper_class.LookupDynamicFunctionAllowPrivate(Symbols::hashCode())); |
| 5228 ASSERT(!hash_code_func.IsNull()); | 5121 ASSERT(!hash_code_func.IsNull()); |
| 5229 hash_code_func = hash_code_func.Clone(cls); | 5122 hash_code_func = hash_code_func.Clone(cls); |
| 5230 enum_members.AddFunction(hash_code_func); | 5123 enum_members.AddFunction(hash_code_func); |
| 5231 | 5124 |
| 5232 cls.AddFields(enum_members.fields()); | 5125 cls.AddFields(enum_members.fields()); |
| 5233 const Array& functions = Array::Handle(Z, enum_members.MakeFunctionsArray()); | 5126 const Array& functions = Array::Handle(Z, enum_members.MakeFunctionsArray()); |
| 5234 cls.SetFunctions(functions); | 5127 cls.SetFunctions(functions); |
| 5235 } | 5128 } |
| 5236 | 5129 |
| 5237 | |
| 5238 // Add an implicit constructor to the given class. | 5130 // Add an implicit constructor to the given class. |
| 5239 void Parser::AddImplicitConstructor(const Class& cls) { | 5131 void Parser::AddImplicitConstructor(const Class& cls) { |
| 5240 // The implicit constructor is unnamed, has no explicit parameter. | 5132 // The implicit constructor is unnamed, has no explicit parameter. |
| 5241 String& ctor_name = String::ZoneHandle(Z, cls.Name()); | 5133 String& ctor_name = String::ZoneHandle(Z, cls.Name()); |
| 5242 ctor_name = Symbols::FromDot(T, ctor_name); | 5134 ctor_name = Symbols::FromDot(T, ctor_name); |
| 5243 // To indicate that this is an implicit constructor, we set the | 5135 // To indicate that this is an implicit constructor, we set the |
| 5244 // token position and end token position of the function | 5136 // token position and end token position of the function |
| 5245 // to the token position of the class. | 5137 // to the token position of the class. |
| 5246 Function& ctor = Function::Handle( | 5138 Function& ctor = Function::Handle( |
| 5247 Z, Function::New(ctor_name, RawFunction::kConstructor, | 5139 Z, Function::New(ctor_name, RawFunction::kConstructor, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5263 | 5155 |
| 5264 AddFormalParamsToFunction(¶ms, ctor); | 5156 AddFormalParamsToFunction(¶ms, ctor); |
| 5265 ctor.set_result_type(Object::dynamic_type()); | 5157 ctor.set_result_type(Object::dynamic_type()); |
| 5266 ResolveSignature(ctor); | 5158 ResolveSignature(ctor); |
| 5267 // The body of the constructor cannot modify the type of the constructed | 5159 // The body of the constructor cannot modify the type of the constructed |
| 5268 // instance, which is passed in as the receiver. | 5160 // instance, which is passed in as the receiver. |
| 5269 ctor.set_result_type(*receiver_type); | 5161 ctor.set_result_type(*receiver_type); |
| 5270 cls.AddFunction(ctor); | 5162 cls.AddFunction(ctor); |
| 5271 } | 5163 } |
| 5272 | 5164 |
| 5273 | |
| 5274 void Parser::CheckFinalInitializationConflicts(const ClassDesc* class_desc, | 5165 void Parser::CheckFinalInitializationConflicts(const ClassDesc* class_desc, |
| 5275 const MemberDesc* member) { | 5166 const MemberDesc* member) { |
| 5276 const ParamList* params = &member->params; | 5167 const ParamList* params = &member->params; |
| 5277 if (!params->has_field_initializer) { | 5168 if (!params->has_field_initializer) { |
| 5278 return; | 5169 return; |
| 5279 } | 5170 } |
| 5280 | 5171 |
| 5281 const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters; | 5172 const ZoneGrowableArray<ParamDesc>& parameters = *params->parameters; |
| 5282 const GrowableArray<const Field*>& fields = class_desc->fields(); | 5173 const GrowableArray<const Field*>& fields = class_desc->fields(); |
| 5283 String& field_name = String::Handle(Z); | 5174 String& field_name = String::Handle(Z); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5298 field_name ^= current_field->name(); | 5189 field_name ^= current_field->name(); |
| 5299 if (param_name.Equals(field_name)) { | 5190 if (param_name.Equals(field_name)) { |
| 5300 ReportError(current_param.name_pos, | 5191 ReportError(current_param.name_pos, |
| 5301 "final field '%s' is already initialized.", | 5192 "final field '%s' is already initialized.", |
| 5302 param_name.ToCString()); | 5193 param_name.ToCString()); |
| 5303 } | 5194 } |
| 5304 } | 5195 } |
| 5305 } | 5196 } |
| 5306 } | 5197 } |
| 5307 | 5198 |
| 5308 | |
| 5309 // Check for cycles in constructor redirection. | 5199 // Check for cycles in constructor redirection. |
| 5310 void Parser::CheckConstructors(ClassDesc* class_desc) { | 5200 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 5311 // Check for cycles in constructor redirection. | 5201 // Check for cycles in constructor redirection. |
| 5312 const GrowableArray<MemberDesc>& members = class_desc->members(); | 5202 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 5313 for (int i = 0; i < members.length(); i++) { | 5203 for (int i = 0; i < members.length(); i++) { |
| 5314 MemberDesc* member = &members[i]; | 5204 MemberDesc* member = &members[i]; |
| 5315 if (member->IsConstructor()) { | 5205 if (member->IsConstructor()) { |
| 5316 // Check that our constructors don't try and reinitialize an initialized | 5206 // Check that our constructors don't try and reinitialize an initialized |
| 5317 // final variable. | 5207 // final variable. |
| 5318 CheckFinalInitializationConflicts(class_desc, member); | 5208 CheckFinalInitializationConflicts(class_desc, member); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5334 // the next redirection. If we can't find the constructor to | 5224 // the next redirection. If we can't find the constructor to |
| 5335 // which the current one redirects, we ignore the unresolved | 5225 // which the current one redirects, we ignore the unresolved |
| 5336 // reference. We'll catch it later when the constructor gets | 5226 // reference. We'll catch it later when the constructor gets |
| 5337 // compiled. | 5227 // compiled. |
| 5338 ctors.Add(member); | 5228 ctors.Add(member); |
| 5339 member = class_desc->LookupMember(*member->redirect_name); | 5229 member = class_desc->LookupMember(*member->redirect_name); |
| 5340 } | 5230 } |
| 5341 } | 5231 } |
| 5342 } | 5232 } |
| 5343 | 5233 |
| 5344 | |
| 5345 void Parser::ParseMixinAppAlias(const GrowableObjectArray& pending_classes, | 5234 void Parser::ParseMixinAppAlias(const GrowableObjectArray& pending_classes, |
| 5346 const Object& tl_owner, | 5235 const Object& tl_owner, |
| 5347 TokenPosition metadata_pos) { | 5236 TokenPosition metadata_pos) { |
| 5348 TRACE_PARSER("ParseMixinAppAlias"); | 5237 TRACE_PARSER("ParseMixinAppAlias"); |
| 5349 const TokenPosition classname_pos = TokenPos(); | 5238 const TokenPosition classname_pos = TokenPos(); |
| 5350 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 5239 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 5351 if (FLAG_trace_parser) { | 5240 if (FLAG_trace_parser) { |
| 5352 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 5241 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 5353 class_name.ToCString()); | 5242 class_name.ToCString()); |
| 5354 } | 5243 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5392 if (CurrentToken() == Token::kIMPLEMENTS) { | 5281 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 5393 ParseInterfaceList(mixin_application); | 5282 ParseInterfaceList(mixin_application); |
| 5394 } | 5283 } |
| 5395 ExpectSemicolon(); | 5284 ExpectSemicolon(); |
| 5396 pending_classes.Add(mixin_application, Heap::kOld); | 5285 pending_classes.Add(mixin_application, Heap::kOld); |
| 5397 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5286 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5398 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); | 5287 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); |
| 5399 } | 5288 } |
| 5400 } | 5289 } |
| 5401 | 5290 |
| 5402 | |
| 5403 // Look ahead to detect if we are seeing ident [ TypeParameters ] ("(" | "="). | 5291 // Look ahead to detect if we are seeing ident [ TypeParameters ] ("(" | "="). |
| 5404 // We need this lookahead to distinguish between the optional return type | 5292 // We need this lookahead to distinguish between the optional return type |
| 5405 // and the alias name of a function type alias. | 5293 // and the alias name of a function type alias. |
| 5406 // Token position remains unchanged. | 5294 // Token position remains unchanged. |
| 5407 bool Parser::IsFunctionTypeAliasName(bool* use_function_type_syntax) { | 5295 bool Parser::IsFunctionTypeAliasName(bool* use_function_type_syntax) { |
| 5408 if (IsIdentifier()) { | 5296 if (IsIdentifier()) { |
| 5409 const Token::Kind ahead = LookaheadToken(1); | 5297 const Token::Kind ahead = LookaheadToken(1); |
| 5410 if ((ahead == Token::kLPAREN) || (ahead == Token::kASSIGN)) { | 5298 if ((ahead == Token::kLPAREN) || (ahead == Token::kASSIGN)) { |
| 5411 *use_function_type_syntax = (ahead == Token::kASSIGN); | 5299 *use_function_type_syntax = (ahead == Token::kASSIGN); |
| 5412 return true; | 5300 return true; |
| 5413 } | 5301 } |
| 5414 } | 5302 } |
| 5415 const TokenPosScope saved_pos(this); | 5303 const TokenPosScope saved_pos(this); |
| 5416 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 5304 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 5417 ConsumeToken(); | 5305 ConsumeToken(); |
| 5418 if (TryParseTypeParameters()) { | 5306 if (TryParseTypeParameters()) { |
| 5419 const Token::Kind current = CurrentToken(); | 5307 const Token::Kind current = CurrentToken(); |
| 5420 if ((current == Token::kLPAREN) || (current == Token::kASSIGN)) { | 5308 if ((current == Token::kLPAREN) || (current == Token::kASSIGN)) { |
| 5421 *use_function_type_syntax = (current == Token::kASSIGN); | 5309 *use_function_type_syntax = (current == Token::kASSIGN); |
| 5422 return true; | 5310 return true; |
| 5423 } | 5311 } |
| 5424 } | 5312 } |
| 5425 } | 5313 } |
| 5426 *use_function_type_syntax = false; | 5314 *use_function_type_syntax = false; |
| 5427 return false; | 5315 return false; |
| 5428 } | 5316 } |
| 5429 | 5317 |
| 5430 | |
| 5431 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 5318 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| 5432 const Object& tl_owner, | 5319 const Object& tl_owner, |
| 5433 TokenPosition metadata_pos) { | 5320 TokenPosition metadata_pos) { |
| 5434 TRACE_PARSER("ParseTypedef"); | 5321 TRACE_PARSER("ParseTypedef"); |
| 5435 TokenPosition declaration_pos = | 5322 TokenPosition declaration_pos = |
| 5436 metadata_pos.IsReal() ? metadata_pos : TokenPos(); | 5323 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
| 5437 ExpectToken(Token::kTYPEDEF); | 5324 ExpectToken(Token::kTYPEDEF); |
| 5438 | 5325 |
| 5439 // Distinguish between two possible typedef forms: | 5326 // Distinguish between two possible typedef forms: |
| 5440 // 1) returnType? identifier typeParameters? formalParameterList ’;’ | 5327 // 1) returnType? identifier typeParameters? formalParameterList ’;’ |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5539 } | 5426 } |
| 5540 // The alias should not be marked as finalized yet, since it needs to be | 5427 // The alias should not be marked as finalized yet, since it needs to be |
| 5541 // checked in the class finalizer for illegal self references. | 5428 // checked in the class finalizer for illegal self references. |
| 5542 ASSERT(!function_type_alias.is_finalized()); | 5429 ASSERT(!function_type_alias.is_finalized()); |
| 5543 pending_classes.Add(function_type_alias, Heap::kOld); | 5430 pending_classes.Add(function_type_alias, Heap::kOld); |
| 5544 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5431 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5545 library_.AddClassMetadata(function_type_alias, tl_owner, metadata_pos); | 5432 library_.AddClassMetadata(function_type_alias, tl_owner, metadata_pos); |
| 5546 } | 5433 } |
| 5547 } | 5434 } |
| 5548 | 5435 |
| 5549 | |
| 5550 // Consumes exactly one right angle bracket. If the current token is | 5436 // Consumes exactly one right angle bracket. If the current token is |
| 5551 // a single bracket token, it is consumed normally. However, if it is | 5437 // a single bracket token, it is consumed normally. However, if it is |
| 5552 // a double bracket, it is replaced by a single bracket token without | 5438 // a double bracket, it is replaced by a single bracket token without |
| 5553 // incrementing the token index. | 5439 // incrementing the token index. |
| 5554 void Parser::ConsumeRightAngleBracket() { | 5440 void Parser::ConsumeRightAngleBracket() { |
| 5555 if (token_kind_ == Token::kGT) { | 5441 if (token_kind_ == Token::kGT) { |
| 5556 ConsumeToken(); | 5442 ConsumeToken(); |
| 5557 } else if (token_kind_ == Token::kSHR) { | 5443 } else if (token_kind_ == Token::kSHR) { |
| 5558 token_kind_ = Token::kGT; | 5444 token_kind_ = Token::kGT; |
| 5559 } else { | 5445 } else { |
| 5560 UNREACHABLE(); | 5446 UNREACHABLE(); |
| 5561 } | 5447 } |
| 5562 } | 5448 } |
| 5563 | 5449 |
| 5564 | |
| 5565 bool Parser::IsPatchAnnotation(TokenPosition pos) { | 5450 bool Parser::IsPatchAnnotation(TokenPosition pos) { |
| 5566 if (pos == TokenPosition::kNoSource) { | 5451 if (pos == TokenPosition::kNoSource) { |
| 5567 return false; | 5452 return false; |
| 5568 } | 5453 } |
| 5569 TokenPosScope saved_pos(this); | 5454 TokenPosScope saved_pos(this); |
| 5570 SetPosition(pos); | 5455 SetPosition(pos); |
| 5571 ExpectToken(Token::kAT); | 5456 ExpectToken(Token::kAT); |
| 5572 return IsSymbol(Symbols::Patch()); | 5457 return IsSymbol(Symbols::Patch()); |
| 5573 } | 5458 } |
| 5574 | 5459 |
| 5575 | |
| 5576 TokenPosition Parser::SkipMetadata() { | 5460 TokenPosition Parser::SkipMetadata() { |
| 5577 if (CurrentToken() != Token::kAT) { | 5461 if (CurrentToken() != Token::kAT) { |
| 5578 return TokenPosition::kNoSource; | 5462 return TokenPosition::kNoSource; |
| 5579 } | 5463 } |
| 5580 TokenPosition metadata_pos = TokenPos(); | 5464 TokenPosition metadata_pos = TokenPos(); |
| 5581 while (CurrentToken() == Token::kAT) { | 5465 while (CurrentToken() == Token::kAT) { |
| 5582 ConsumeToken(); | 5466 ConsumeToken(); |
| 5583 ExpectIdentifier("identifier expected"); | 5467 ExpectIdentifier("identifier expected"); |
| 5584 if (CurrentToken() == Token::kPERIOD) { | 5468 if (CurrentToken() == Token::kPERIOD) { |
| 5585 ConsumeToken(); | 5469 ConsumeToken(); |
| 5586 ExpectIdentifier("identifier expected"); | 5470 ExpectIdentifier("identifier expected"); |
| 5587 if (CurrentToken() == Token::kPERIOD) { | 5471 if (CurrentToken() == Token::kPERIOD) { |
| 5588 ConsumeToken(); | 5472 ConsumeToken(); |
| 5589 ExpectIdentifier("identifier expected"); | 5473 ExpectIdentifier("identifier expected"); |
| 5590 } | 5474 } |
| 5591 } | 5475 } |
| 5592 if (CurrentToken() == Token::kLPAREN) { | 5476 if (CurrentToken() == Token::kLPAREN) { |
| 5593 SkipToMatchingParenthesis(); | 5477 SkipToMatchingParenthesis(); |
| 5594 } | 5478 } |
| 5595 } | 5479 } |
| 5596 return metadata_pos; | 5480 return metadata_pos; |
| 5597 } | 5481 } |
| 5598 | 5482 |
| 5599 | |
| 5600 void Parser::SkipTypeArguments() { | 5483 void Parser::SkipTypeArguments() { |
| 5601 if (CurrentToken() == Token::kLT) { | 5484 if (CurrentToken() == Token::kLT) { |
| 5602 do { | 5485 do { |
| 5603 ConsumeToken(); | 5486 ConsumeToken(); |
| 5604 SkipTypeOrFunctionType(true); | 5487 SkipTypeOrFunctionType(true); |
| 5605 } while (CurrentToken() == Token::kCOMMA); | 5488 } while (CurrentToken() == Token::kCOMMA); |
| 5606 Token::Kind token = CurrentToken(); | 5489 Token::Kind token = CurrentToken(); |
| 5607 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5490 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 5608 ConsumeRightAngleBracket(); | 5491 ConsumeRightAngleBracket(); |
| 5609 } else { | 5492 } else { |
| 5610 ReportError("right angle bracket expected"); | 5493 ReportError("right angle bracket expected"); |
| 5611 } | 5494 } |
| 5612 } | 5495 } |
| 5613 } | 5496 } |
| 5614 | 5497 |
| 5615 | |
| 5616 void Parser::SkipTypeParameters() { | 5498 void Parser::SkipTypeParameters() { |
| 5617 // Function already parsed, no need to check FLAG_generic_method_syntax. | 5499 // Function already parsed, no need to check FLAG_generic_method_syntax. |
| 5618 if (IsTypeParameters()) { | 5500 if (IsTypeParameters()) { |
| 5619 const bool skipped = TryParseTypeParameters(); | 5501 const bool skipped = TryParseTypeParameters(); |
| 5620 ASSERT(skipped); | 5502 ASSERT(skipped); |
| 5621 } | 5503 } |
| 5622 } | 5504 } |
| 5623 | 5505 |
| 5624 | |
| 5625 void Parser::SkipType(bool allow_void) { | 5506 void Parser::SkipType(bool allow_void) { |
| 5626 if (CurrentToken() == Token::kVOID) { | 5507 if (CurrentToken() == Token::kVOID) { |
| 5627 if (!allow_void) { | 5508 if (!allow_void) { |
| 5628 ReportError("'void' not allowed here"); | 5509 ReportError("'void' not allowed here"); |
| 5629 } | 5510 } |
| 5630 ConsumeToken(); | 5511 ConsumeToken(); |
| 5631 } else { | 5512 } else { |
| 5632 ExpectIdentifier("type name expected"); | 5513 ExpectIdentifier("type name expected"); |
| 5633 if (CurrentToken() == Token::kPERIOD) { | 5514 if (CurrentToken() == Token::kPERIOD) { |
| 5634 ConsumeToken(); | 5515 ConsumeToken(); |
| 5635 ExpectIdentifier("name expected"); | 5516 ExpectIdentifier("name expected"); |
| 5636 } | 5517 } |
| 5637 SkipTypeArguments(); | 5518 SkipTypeArguments(); |
| 5638 } | 5519 } |
| 5639 } | 5520 } |
| 5640 | 5521 |
| 5641 | |
| 5642 void Parser::SkipTypeOrFunctionType(bool allow_void) { | 5522 void Parser::SkipTypeOrFunctionType(bool allow_void) { |
| 5643 if (CurrentToken() == Token::kVOID) { | 5523 if (CurrentToken() == Token::kVOID) { |
| 5644 TokenPosition void_pos = TokenPos(); | 5524 TokenPosition void_pos = TokenPos(); |
| 5645 ConsumeToken(); | 5525 ConsumeToken(); |
| 5646 // 'void' is always allowed as result type of a function type. | 5526 // 'void' is always allowed as result type of a function type. |
| 5647 if (!allow_void && !IsFunctionTypeSymbol()) { | 5527 if (!allow_void && !IsFunctionTypeSymbol()) { |
| 5648 ReportError(void_pos, "'void' not allowed here"); | 5528 ReportError(void_pos, "'void' not allowed here"); |
| 5649 } | 5529 } |
| 5650 } else if (!IsFunctionTypeSymbol()) { | 5530 } else if (!IsFunctionTypeSymbol()) { |
| 5651 // Including 'Function' not followed by '(' or '<'. | 5531 // Including 'Function' not followed by '(' or '<'. |
| 5652 SkipType(false); | 5532 SkipType(false); |
| 5653 } | 5533 } |
| 5654 while (IsFunctionTypeSymbol()) { | 5534 while (IsFunctionTypeSymbol()) { |
| 5655 ConsumeToken(); | 5535 ConsumeToken(); |
| 5656 SkipTypeArguments(); | 5536 SkipTypeArguments(); |
| 5657 if (CurrentToken() == Token::kLPAREN) { | 5537 if (CurrentToken() == Token::kLPAREN) { |
| 5658 SkipToMatchingParenthesis(); | 5538 SkipToMatchingParenthesis(); |
| 5659 } else { | 5539 } else { |
| 5660 ReportError("'(' expected"); | 5540 ReportError("'(' expected"); |
| 5661 } | 5541 } |
| 5662 } | 5542 } |
| 5663 } | 5543 } |
| 5664 | 5544 |
| 5665 | |
| 5666 void Parser::ParseTypeParameters(bool parameterizing_class) { | 5545 void Parser::ParseTypeParameters(bool parameterizing_class) { |
| 5667 TRACE_PARSER("ParseTypeParameters"); | 5546 TRACE_PARSER("ParseTypeParameters"); |
| 5668 if (CurrentToken() == Token::kLT) { | 5547 if (CurrentToken() == Token::kLT) { |
| 5669 GrowableArray<AbstractType*> type_parameters_array(Z, 2); | 5548 GrowableArray<AbstractType*> type_parameters_array(Z, 2); |
| 5670 intptr_t index = 0; | 5549 intptr_t index = 0; |
| 5671 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5550 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
| 5672 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5551 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
| 5673 String& existing_type_parameter_name = String::Handle(Z); | 5552 String& existing_type_parameter_name = String::Handle(Z); |
| 5674 AbstractType& type_parameter_bound = Type::Handle(Z); | 5553 AbstractType& type_parameter_bound = Type::Handle(Z); |
| 5675 do { | 5554 do { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5740 const intptr_t num_types = type_parameters.Length(); | 5619 const intptr_t num_types = type_parameters.Length(); |
| 5741 for (intptr_t i = 0; i < num_types; i++) { | 5620 for (intptr_t i = 0; i < num_types; i++) { |
| 5742 type_parameter ^= type_parameters.TypeAt(i); | 5621 type_parameter ^= type_parameters.TypeAt(i); |
| 5743 type_parameter_bound = type_parameter.bound(); | 5622 type_parameter_bound = type_parameter.bound(); |
| 5744 ResolveType(&type_parameter_bound); | 5623 ResolveType(&type_parameter_bound); |
| 5745 type_parameter.set_bound(type_parameter_bound); | 5624 type_parameter.set_bound(type_parameter_bound); |
| 5746 } | 5625 } |
| 5747 } | 5626 } |
| 5748 } | 5627 } |
| 5749 | 5628 |
| 5750 | |
| 5751 RawTypeArguments* Parser::ParseTypeArguments( | 5629 RawTypeArguments* Parser::ParseTypeArguments( |
| 5752 ClassFinalizer::FinalizationKind finalization) { | 5630 ClassFinalizer::FinalizationKind finalization) { |
| 5753 TRACE_PARSER("ParseTypeArguments"); | 5631 TRACE_PARSER("ParseTypeArguments"); |
| 5754 if (CurrentToken() == Token::kLT) { | 5632 if (CurrentToken() == Token::kLT) { |
| 5755 GrowableArray<AbstractType*> types; | 5633 GrowableArray<AbstractType*> types; |
| 5756 AbstractType& type = AbstractType::Handle(Z); | 5634 AbstractType& type = AbstractType::Handle(Z); |
| 5757 do { | 5635 do { |
| 5758 ConsumeToken(); | 5636 ConsumeToken(); |
| 5759 type = ParseTypeOrFunctionType(true, finalization); | 5637 type = ParseTypeOrFunctionType(true, finalization); |
| 5760 // Map a malformed type argument to dynamic. | 5638 // Map a malformed type argument to dynamic. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5773 TypeArguments& type_args = TypeArguments::Handle(NewTypeArguments(types)); | 5651 TypeArguments& type_args = TypeArguments::Handle(NewTypeArguments(types)); |
| 5774 if (finalization == ClassFinalizer::kCanonicalize) { | 5652 if (finalization == ClassFinalizer::kCanonicalize) { |
| 5775 type_args = type_args.Canonicalize(); | 5653 type_args = type_args.Canonicalize(); |
| 5776 } | 5654 } |
| 5777 return type_args.raw(); | 5655 return type_args.raw(); |
| 5778 } | 5656 } |
| 5779 } | 5657 } |
| 5780 return TypeArguments::null(); | 5658 return TypeArguments::null(); |
| 5781 } | 5659 } |
| 5782 | 5660 |
| 5783 | |
| 5784 // Parse interface list and add to class cls. | 5661 // Parse interface list and add to class cls. |
| 5785 void Parser::ParseInterfaceList(const Class& cls) { | 5662 void Parser::ParseInterfaceList(const Class& cls) { |
| 5786 TRACE_PARSER("ParseInterfaceList"); | 5663 TRACE_PARSER("ParseInterfaceList"); |
| 5787 ASSERT(CurrentToken() == Token::kIMPLEMENTS); | 5664 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 5788 const GrowableObjectArray& all_interfaces = | 5665 const GrowableObjectArray& all_interfaces = |
| 5789 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 5666 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 5790 AbstractType& interface = AbstractType::Handle(Z); | 5667 AbstractType& interface = AbstractType::Handle(Z); |
| 5791 // First get all the interfaces already implemented by class. | 5668 // First get all the interfaces already implemented by class. |
| 5792 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); | 5669 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); |
| 5793 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 5670 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 5794 interface ^= cls_interfaces.At(i); | 5671 interface ^= cls_interfaces.At(i); |
| 5795 all_interfaces.Add(interface, Heap::kOld); | 5672 all_interfaces.Add(interface, Heap::kOld); |
| 5796 } | 5673 } |
| 5797 // Now parse and add the new interfaces. | 5674 // Now parse and add the new interfaces. |
| 5798 do { | 5675 do { |
| 5799 ConsumeToken(); | 5676 ConsumeToken(); |
| 5800 TokenPosition interface_pos = TokenPos(); | 5677 TokenPosition interface_pos = TokenPos(); |
| 5801 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 5678 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5802 if (interface.IsTypeParameter()) { | 5679 if (interface.IsTypeParameter()) { |
| 5803 ReportError(interface_pos, | 5680 ReportError(interface_pos, |
| 5804 "type parameter '%s' may not be used in interface list", | 5681 "type parameter '%s' may not be used in interface list", |
| 5805 String::Handle(Z, interface.UserVisibleName()).ToCString()); | 5682 String::Handle(Z, interface.UserVisibleName()).ToCString()); |
| 5806 } | 5683 } |
| 5807 all_interfaces.Add(interface, Heap::kOld); | 5684 all_interfaces.Add(interface, Heap::kOld); |
| 5808 } while (CurrentToken() == Token::kCOMMA); | 5685 } while (CurrentToken() == Token::kCOMMA); |
| 5809 cls_interfaces = Array::MakeFixedLength(all_interfaces); | 5686 cls_interfaces = Array::MakeFixedLength(all_interfaces); |
| 5810 cls.set_interfaces(cls_interfaces); | 5687 cls.set_interfaces(cls_interfaces); |
| 5811 } | 5688 } |
| 5812 | 5689 |
| 5813 | |
| 5814 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 5690 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 5815 TRACE_PARSER("ParseMixins"); | 5691 TRACE_PARSER("ParseMixins"); |
| 5816 ASSERT(CurrentToken() == Token::kWITH); | 5692 ASSERT(CurrentToken() == Token::kWITH); |
| 5817 const GrowableObjectArray& mixin_types = | 5693 const GrowableObjectArray& mixin_types = |
| 5818 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 5694 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 5819 AbstractType& mixin_type = AbstractType::Handle(Z); | 5695 AbstractType& mixin_type = AbstractType::Handle(Z); |
| 5820 do { | 5696 do { |
| 5821 ConsumeToken(); | 5697 ConsumeToken(); |
| 5822 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5698 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5823 if (mixin_type.IsDynamicType()) { | 5699 if (mixin_type.IsDynamicType()) { |
| 5824 // The string 'dynamic' is not resolved yet at this point, but a malformed | 5700 // The string 'dynamic' is not resolved yet at this point, but a malformed |
| 5825 // type mapped to dynamic can be encountered here. | 5701 // type mapped to dynamic can be encountered here. |
| 5826 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); | 5702 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
| 5827 } | 5703 } |
| 5828 if (mixin_type.IsTypeParameter()) { | 5704 if (mixin_type.IsTypeParameter()) { |
| 5829 ReportError(mixin_type.token_pos(), | 5705 ReportError(mixin_type.token_pos(), |
| 5830 "mixin type '%s' may not be a type parameter", | 5706 "mixin type '%s' may not be a type parameter", |
| 5831 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); | 5707 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); |
| 5832 } | 5708 } |
| 5833 mixin_types.Add(mixin_type, Heap::kOld); | 5709 mixin_types.Add(mixin_type, Heap::kOld); |
| 5834 } while (CurrentToken() == Token::kCOMMA); | 5710 } while (CurrentToken() == Token::kCOMMA); |
| 5835 return MixinAppType::New( | 5711 return MixinAppType::New( |
| 5836 super_type, Array::Handle(Z, Array::MakeFixedLength(mixin_types))); | 5712 super_type, Array::Handle(Z, Array::MakeFixedLength(mixin_types))); |
| 5837 } | 5713 } |
| 5838 | 5714 |
| 5839 | |
| 5840 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5715 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 5841 const Object& owner, | 5716 const Object& owner, |
| 5842 TokenPosition metadata_pos) { | 5717 TokenPosition metadata_pos) { |
| 5843 TRACE_PARSER("ParseTopLevelVariable"); | 5718 TRACE_PARSER("ParseTopLevelVariable"); |
| 5844 const bool is_const = (CurrentToken() == Token::kCONST); | 5719 const bool is_const = (CurrentToken() == Token::kCONST); |
| 5845 // Const fields are implicitly final. | 5720 // Const fields are implicitly final. |
| 5846 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5721 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 5847 const bool is_static = true; | 5722 const bool is_static = true; |
| 5848 const AbstractType& type = AbstractType::ZoneHandle( | 5723 const AbstractType& type = AbstractType::ZoneHandle( |
| 5849 Z, ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5724 Z, ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5920 ConsumeToken(); | 5795 ConsumeToken(); |
| 5921 } else if (CurrentToken() == Token::kSEMICOLON) { | 5796 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 5922 ConsumeToken(); | 5797 ConsumeToken(); |
| 5923 break; | 5798 break; |
| 5924 } else { | 5799 } else { |
| 5925 ExpectSemicolon(); // Reports error. | 5800 ExpectSemicolon(); // Reports error. |
| 5926 } | 5801 } |
| 5927 } | 5802 } |
| 5928 } | 5803 } |
| 5929 | 5804 |
| 5930 | |
| 5931 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { | 5805 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { |
| 5932 if (IsSymbol(Symbols::Async())) { | 5806 if (IsSymbol(Symbols::Async())) { |
| 5933 ConsumeToken(); | 5807 ConsumeToken(); |
| 5934 if (CurrentToken() == Token::kMUL) { | 5808 if (CurrentToken() == Token::kMUL) { |
| 5935 const bool enableAsyncStar = true; | 5809 const bool enableAsyncStar = true; |
| 5936 if (!enableAsyncStar) { | 5810 if (!enableAsyncStar) { |
| 5937 ReportError("async* generator functions are not yet supported"); | 5811 ReportError("async* generator functions are not yet supported"); |
| 5938 } | 5812 } |
| 5939 ConsumeToken(); | 5813 ConsumeToken(); |
| 5940 return RawFunction::kAsyncGen; | 5814 return RawFunction::kAsyncGen; |
| 5941 } else { | 5815 } else { |
| 5942 return RawFunction::kAsync; | 5816 return RawFunction::kAsync; |
| 5943 } | 5817 } |
| 5944 } else if (IsSymbol(Symbols::Sync()) && (LookaheadToken(1) == Token::kMUL)) { | 5818 } else if (IsSymbol(Symbols::Sync()) && (LookaheadToken(1) == Token::kMUL)) { |
| 5945 const bool enableSyncStar = true; | 5819 const bool enableSyncStar = true; |
| 5946 if (!enableSyncStar) { | 5820 if (!enableSyncStar) { |
| 5947 ReportError("sync* generator functions are not yet supported"); | 5821 ReportError("sync* generator functions are not yet supported"); |
| 5948 } | 5822 } |
| 5949 ConsumeToken(); | 5823 ConsumeToken(); |
| 5950 ConsumeToken(); | 5824 ConsumeToken(); |
| 5951 return RawFunction::kSyncGen; | 5825 return RawFunction::kSyncGen; |
| 5952 } | 5826 } |
| 5953 return RawFunction::kNoModifier; | 5827 return RawFunction::kNoModifier; |
| 5954 } | 5828 } |
| 5955 | 5829 |
| 5956 | |
| 5957 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5830 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 5958 const Object& owner, | 5831 const Object& owner, |
| 5959 TokenPosition metadata_pos) { | 5832 TokenPosition metadata_pos) { |
| 5960 TRACE_PARSER("ParseTopLevelFunction"); | 5833 TRACE_PARSER("ParseTopLevelFunction"); |
| 5961 const TokenPosition decl_begin_pos = TokenPos(); | 5834 const TokenPosition decl_begin_pos = TokenPos(); |
| 5962 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5835 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
| 5963 bool is_external = false; | 5836 bool is_external = false; |
| 5964 bool is_patch = false; | 5837 bool is_patch = false; |
| 5965 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 5838 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
| 5966 is_patch = true; | 5839 is_patch = true; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6079 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); | 5952 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); |
| 6080 ASSERT(!replaced_func.IsNull()); | 5953 ASSERT(!replaced_func.IsNull()); |
| 6081 toplevel_cls.RemoveFunction(replaced_func); | 5954 toplevel_cls.RemoveFunction(replaced_func); |
| 6082 library_.ReplaceObject(func, func_name); | 5955 library_.ReplaceObject(func, func_name); |
| 6083 } | 5956 } |
| 6084 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5957 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 6085 library_.AddFunctionMetadata(func, metadata_pos); | 5958 library_.AddFunctionMetadata(func, metadata_pos); |
| 6086 } | 5959 } |
| 6087 } | 5960 } |
| 6088 | 5961 |
| 6089 | |
| 6090 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 5962 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
| 6091 const Object& owner, | 5963 const Object& owner, |
| 6092 TokenPosition metadata_pos) { | 5964 TokenPosition metadata_pos) { |
| 6093 TRACE_PARSER("ParseTopLevelAccessor"); | 5965 TRACE_PARSER("ParseTopLevelAccessor"); |
| 6094 const TokenPosition decl_begin_pos = TokenPos(); | 5966 const TokenPosition decl_begin_pos = TokenPos(); |
| 6095 const bool is_static = true; | 5967 const bool is_static = true; |
| 6096 bool is_external = false; | 5968 bool is_external = false; |
| 6097 bool is_patch = false; | 5969 bool is_patch = false; |
| 6098 AbstractType& result_type = AbstractType::Handle(Z); | 5970 AbstractType& result_type = AbstractType::Handle(Z); |
| 6099 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 5971 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6199 ExpectSemicolon(); | 6071 ExpectSemicolon(); |
| 6200 } else if (IsSymbol(Symbols::Native())) { | 6072 } else if (IsSymbol(Symbols::Native())) { |
| 6201 native_name = &ParseNativeDeclaration(); | 6073 native_name = &ParseNativeDeclaration(); |
| 6202 accessor_end_pos = TokenPos(); | 6074 accessor_end_pos = TokenPos(); |
| 6203 ExpectSemicolon(); | 6075 ExpectSemicolon(); |
| 6204 is_native = true; | 6076 is_native = true; |
| 6205 } else { | 6077 } else { |
| 6206 ReportError("function block expected"); | 6078 ReportError("function block expected"); |
| 6207 } | 6079 } |
| 6208 Function& func = Function::Handle( | 6080 Function& func = Function::Handle( |
| 6209 Z, Function::New(accessor_name, is_getter ? RawFunction::kGetterFunction | 6081 Z, Function::New(accessor_name, |
| 6210 : RawFunction::kSetterFunction, | 6082 is_getter ? RawFunction::kGetterFunction |
| 6083 : RawFunction::kSetterFunction, |
| 6211 is_static, | 6084 is_static, |
| 6212 /* is_const = */ false, | 6085 /* is_const = */ false, |
| 6213 /* is_abstract = */ false, is_external, is_native, owner, | 6086 /* is_abstract = */ false, is_external, is_native, owner, |
| 6214 decl_begin_pos)); | 6087 decl_begin_pos)); |
| 6215 func.set_result_type(result_type); | 6088 func.set_result_type(result_type); |
| 6216 func.set_end_token_pos(accessor_end_pos); | 6089 func.set_end_token_pos(accessor_end_pos); |
| 6217 func.set_modifier(func_modifier); | 6090 func.set_modifier(func_modifier); |
| 6218 if (is_native) { | 6091 if (is_native) { |
| 6219 func.set_is_debuggable(false); | 6092 func.set_is_debuggable(false); |
| 6220 func.set_native_name(*native_name); | 6093 func.set_native_name(*native_name); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6236 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); | 6109 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); |
| 6237 ASSERT(!replaced_func.IsNull()); | 6110 ASSERT(!replaced_func.IsNull()); |
| 6238 toplevel_cls.RemoveFunction(replaced_func); | 6111 toplevel_cls.RemoveFunction(replaced_func); |
| 6239 library_.ReplaceObject(func, accessor_name); | 6112 library_.ReplaceObject(func, accessor_name); |
| 6240 } | 6113 } |
| 6241 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 6114 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 6242 library_.AddFunctionMetadata(func, metadata_pos); | 6115 library_.AddFunctionMetadata(func, metadata_pos); |
| 6243 } | 6116 } |
| 6244 } | 6117 } |
| 6245 | 6118 |
| 6246 | |
| 6247 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, | 6119 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, |
| 6248 TokenPosition token_pos, | 6120 TokenPosition token_pos, |
| 6249 const String& url) { | 6121 const String& url) { |
| 6250 Dart_LibraryTagHandler handler = I->library_tag_handler(); | 6122 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
| 6251 if (handler == NULL) { | 6123 if (handler == NULL) { |
| 6252 if (url.StartsWith(Symbols::DartScheme())) { | 6124 if (url.StartsWith(Symbols::DartScheme())) { |
| 6253 if (tag == Dart_kCanonicalizeUrl) { | 6125 if (tag == Dart_kCanonicalizeUrl) { |
| 6254 return url.raw(); | 6126 return url.raw(); |
| 6255 } | 6127 } |
| 6256 return Object::null(); | 6128 return Object::null(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 6276 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); | 6148 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); |
| 6277 } | 6149 } |
| 6278 if (tag == Dart_kCanonicalizeUrl) { | 6150 if (tag == Dart_kCanonicalizeUrl) { |
| 6279 if (!result.IsString()) { | 6151 if (!result.IsString()) { |
| 6280 ReportError(token_pos, "library handler failed URI canonicalization"); | 6152 ReportError(token_pos, "library handler failed URI canonicalization"); |
| 6281 } | 6153 } |
| 6282 } | 6154 } |
| 6283 return result.raw(); | 6155 return result.raw(); |
| 6284 } | 6156 } |
| 6285 | 6157 |
| 6286 | |
| 6287 void Parser::ParseLibraryName() { | 6158 void Parser::ParseLibraryName() { |
| 6288 ASSERT(CurrentToken() == Token::kLIBRARY); | 6159 ASSERT(CurrentToken() == Token::kLIBRARY); |
| 6289 ConsumeToken(); | 6160 ConsumeToken(); |
| 6290 String& lib_name = *ExpectIdentifier("library name expected"); | 6161 String& lib_name = *ExpectIdentifier("library name expected"); |
| 6291 if (CurrentToken() == Token::kPERIOD) { | 6162 if (CurrentToken() == Token::kPERIOD) { |
| 6292 GrowableHandlePtrArray<const String> pieces(Z, 3); | 6163 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 6293 pieces.Add(lib_name); | 6164 pieces.Add(lib_name); |
| 6294 while (CurrentToken() == Token::kPERIOD) { | 6165 while (CurrentToken() == Token::kPERIOD) { |
| 6295 ConsumeToken(); | 6166 ConsumeToken(); |
| 6296 pieces.Add(Symbols::Dot()); | 6167 pieces.Add(Symbols::Dot()); |
| 6297 pieces.Add(*ExpectIdentifier("malformed library name")); | 6168 pieces.Add(*ExpectIdentifier("malformed library name")); |
| 6298 } | 6169 } |
| 6299 lib_name = Symbols::FromConcatAll(T, pieces); | 6170 lib_name = Symbols::FromConcatAll(T, pieces); |
| 6300 } | 6171 } |
| 6301 library_.SetName(lib_name); | 6172 library_.SetName(lib_name); |
| 6302 ExpectSemicolon(); | 6173 ExpectSemicolon(); |
| 6303 } | 6174 } |
| 6304 | 6175 |
| 6305 | |
| 6306 void Parser::ParseIdentList(GrowableObjectArray* names) { | 6176 void Parser::ParseIdentList(GrowableObjectArray* names) { |
| 6307 if (!IsIdentifier()) { | 6177 if (!IsIdentifier()) { |
| 6308 ReportError("identifier expected"); | 6178 ReportError("identifier expected"); |
| 6309 } | 6179 } |
| 6310 while (IsIdentifier()) { | 6180 while (IsIdentifier()) { |
| 6311 names->Add(*CurrentLiteral(), allocation_space_); | 6181 names->Add(*CurrentLiteral(), allocation_space_); |
| 6312 ConsumeToken(); // Identifier. | 6182 ConsumeToken(); // Identifier. |
| 6313 if (CurrentToken() != Token::kCOMMA) { | 6183 if (CurrentToken() != Token::kCOMMA) { |
| 6314 return; | 6184 return; |
| 6315 } | 6185 } |
| 6316 ConsumeToken(); // Comma. | 6186 ConsumeToken(); // Comma. |
| 6317 } | 6187 } |
| 6318 } | 6188 } |
| 6319 | 6189 |
| 6320 | |
| 6321 void Parser::ParseLibraryImportExport(const Object& tl_owner, | 6190 void Parser::ParseLibraryImportExport(const Object& tl_owner, |
| 6322 TokenPosition metadata_pos) { | 6191 TokenPosition metadata_pos) { |
| 6323 ASSERT(Thread::Current()->IsMutatorThread()); | 6192 ASSERT(Thread::Current()->IsMutatorThread()); |
| 6324 bool is_import = (CurrentToken() == Token::kIMPORT); | 6193 bool is_import = (CurrentToken() == Token::kIMPORT); |
| 6325 bool is_export = (CurrentToken() == Token::kEXPORT); | 6194 bool is_export = (CurrentToken() == Token::kEXPORT); |
| 6326 ASSERT(is_import || is_export); | 6195 ASSERT(is_import || is_export); |
| 6327 const TokenPosition import_pos = TokenPos(); | 6196 const TokenPosition import_pos = TokenPos(); |
| 6328 ConsumeToken(); | 6197 ConsumeToken(); |
| 6329 CheckToken(Token::kSTRING, "library url expected"); | 6198 CheckToken(Token::kSTRING, "library url expected"); |
| 6330 AstNode* url_literal = ParseStringLiteral(false); | 6199 AstNode* url_literal = ParseStringLiteral(false); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6492 LibraryPrefix::New(prefix, ns, is_deferred_import, library_); | 6361 LibraryPrefix::New(prefix, ns, is_deferred_import, library_); |
| 6493 library_.AddObject(library_prefix, prefix); | 6362 library_.AddObject(library_prefix, prefix); |
| 6494 } | 6363 } |
| 6495 } | 6364 } |
| 6496 } else { | 6365 } else { |
| 6497 ASSERT(is_export); | 6366 ASSERT(is_export); |
| 6498 library_.AddExport(ns); | 6367 library_.AddExport(ns); |
| 6499 } | 6368 } |
| 6500 } | 6369 } |
| 6501 | 6370 |
| 6502 | |
| 6503 void Parser::ParseLibraryPart() { | 6371 void Parser::ParseLibraryPart() { |
| 6504 const TokenPosition source_pos = TokenPos(); | 6372 const TokenPosition source_pos = TokenPos(); |
| 6505 ConsumeToken(); // Consume "part". | 6373 ConsumeToken(); // Consume "part". |
| 6506 if (IsSymbol(Symbols::Of())) { | 6374 if (IsSymbol(Symbols::Of())) { |
| 6507 ReportError("part of declarations are not allowed in script files"); | 6375 ReportError("part of declarations are not allowed in script files"); |
| 6508 } | 6376 } |
| 6509 CheckToken(Token::kSTRING, "url expected"); | 6377 CheckToken(Token::kSTRING, "url expected"); |
| 6510 AstNode* url_literal = ParseStringLiteral(false); | 6378 AstNode* url_literal = ParseStringLiteral(false); |
| 6511 ASSERT(url_literal->IsLiteralNode()); | 6379 ASSERT(url_literal->IsLiteralNode()); |
| 6512 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 6380 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
| 6513 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 6381 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
| 6514 ExpectSemicolon(); | 6382 ExpectSemicolon(); |
| 6515 const String& canon_url = String::CheckedHandle( | 6383 const String& canon_url = String::CheckedHandle( |
| 6516 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); | 6384 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); |
| 6517 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); | 6385 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); |
| 6518 } | 6386 } |
| 6519 | 6387 |
| 6520 | |
| 6521 void Parser::ParseLibraryDefinition(const Object& tl_owner) { | 6388 void Parser::ParseLibraryDefinition(const Object& tl_owner) { |
| 6522 TRACE_PARSER("ParseLibraryDefinition"); | 6389 TRACE_PARSER("ParseLibraryDefinition"); |
| 6523 | 6390 |
| 6524 // Handle the script tag. | 6391 // Handle the script tag. |
| 6525 if (CurrentToken() == Token::kSCRIPTTAG) { | 6392 if (CurrentToken() == Token::kSCRIPTTAG) { |
| 6526 // Nothing to do for script tags except to skip them. | 6393 // Nothing to do for script tags except to skip them. |
| 6527 ConsumeToken(); | 6394 ConsumeToken(); |
| 6528 } | 6395 } |
| 6529 | 6396 |
| 6530 ASSERT(script_.kind() != RawScript::kSourceTag); | 6397 ASSERT(script_.kind() != RawScript::kSourceTag); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6563 library_.AddImport(core_ns); | 6430 library_.AddImport(core_ns); |
| 6564 } | 6431 } |
| 6565 while (CurrentToken() == Token::kPART) { | 6432 while (CurrentToken() == Token::kPART) { |
| 6566 ParseLibraryPart(); | 6433 ParseLibraryPart(); |
| 6567 rewind_pos = TokenPos(); | 6434 rewind_pos = TokenPos(); |
| 6568 metadata_pos = SkipMetadata(); | 6435 metadata_pos = SkipMetadata(); |
| 6569 } | 6436 } |
| 6570 SetPosition(rewind_pos); | 6437 SetPosition(rewind_pos); |
| 6571 } | 6438 } |
| 6572 | 6439 |
| 6573 | |
| 6574 void Parser::ParsePartHeader() { | 6440 void Parser::ParsePartHeader() { |
| 6575 SkipMetadata(); | 6441 SkipMetadata(); |
| 6576 CheckToken(Token::kPART, "'part of' expected"); | 6442 CheckToken(Token::kPART, "'part of' expected"); |
| 6577 ConsumeToken(); | 6443 ConsumeToken(); |
| 6578 if (!IsSymbol(Symbols::Of())) { | 6444 if (!IsSymbol(Symbols::Of())) { |
| 6579 ReportError("'part of' expected"); | 6445 ReportError("'part of' expected"); |
| 6580 } | 6446 } |
| 6581 ConsumeToken(); | 6447 ConsumeToken(); |
| 6582 // The VM is not required to check that the library name or URI matches the | 6448 // The VM is not required to check that the library name or URI matches the |
| 6583 // name or URI of the current library, so we ignore them. | 6449 // name or URI of the current library, so we ignore them. |
| 6584 if (CurrentToken() == Token::kSTRING) { | 6450 if (CurrentToken() == Token::kSTRING) { |
| 6585 ParseStringLiteral(false); | 6451 ParseStringLiteral(false); |
| 6586 } else { | 6452 } else { |
| 6587 ExpectIdentifier("library name expected"); | 6453 ExpectIdentifier("library name expected"); |
| 6588 while (CurrentToken() == Token::kPERIOD) { | 6454 while (CurrentToken() == Token::kPERIOD) { |
| 6589 ConsumeToken(); | 6455 ConsumeToken(); |
| 6590 ExpectIdentifier("malformed library name"); | 6456 ExpectIdentifier("malformed library name"); |
| 6591 } | 6457 } |
| 6592 } | 6458 } |
| 6593 ExpectSemicolon(); | 6459 ExpectSemicolon(); |
| 6594 } | 6460 } |
| 6595 | 6461 |
| 6596 | |
| 6597 void Parser::ParseTopLevel() { | 6462 void Parser::ParseTopLevel() { |
| 6598 TRACE_PARSER("ParseTopLevel"); | 6463 TRACE_PARSER("ParseTopLevel"); |
| 6599 // Collect the classes found at the top level in this growable array. | 6464 // Collect the classes found at the top level in this growable array. |
| 6600 // They need to be registered with class finalization after parsing | 6465 // They need to be registered with class finalization after parsing |
| 6601 // has been completed. | 6466 // has been completed. |
| 6602 ObjectStore* object_store = I->object_store(); | 6467 ObjectStore* object_store = I->object_store(); |
| 6603 const GrowableObjectArray& pending_classes = | 6468 const GrowableObjectArray& pending_classes = |
| 6604 GrowableObjectArray::Handle(Z, object_store->pending_classes()); | 6469 GrowableObjectArray::Handle(Z, object_store->pending_classes()); |
| 6605 SetPosition(TokenPosition::kMinSource); | 6470 SetPosition(TokenPosition::kMinSource); |
| 6606 is_top_level_ = true; | 6471 is_top_level_ = true; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6661 } | 6526 } |
| 6662 for (intptr_t i = 0; i < top_level.functions().length(); i++) { | 6527 for (intptr_t i = 0; i < top_level.functions().length(); i++) { |
| 6663 toplevel_class.AddFunction(*top_level.functions()[i]); | 6528 toplevel_class.AddFunction(*top_level.functions()[i]); |
| 6664 } | 6529 } |
| 6665 if (toplevel_class.is_finalized()) { | 6530 if (toplevel_class.is_finalized()) { |
| 6666 toplevel_class.ResetFinalization(); | 6531 toplevel_class.ResetFinalization(); |
| 6667 } | 6532 } |
| 6668 pending_classes.Add(toplevel_class, Heap::kOld); | 6533 pending_classes.Add(toplevel_class, Heap::kOld); |
| 6669 } | 6534 } |
| 6670 | 6535 |
| 6671 | |
| 6672 void Parser::CheckStack() { | 6536 void Parser::CheckStack() { |
| 6673 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); | 6537 volatile uword c_stack_pos = Thread::GetCurrentStackPointer(); |
| 6674 volatile uword c_stack_base = OSThread::Current()->stack_base(); | 6538 volatile uword c_stack_base = OSThread::Current()->stack_base(); |
| 6675 volatile uword c_stack_limit = | 6539 volatile uword c_stack_limit = |
| 6676 c_stack_base - OSThread::GetSpecifiedStackSize(); | 6540 c_stack_base - OSThread::GetSpecifiedStackSize(); |
| 6677 // Note: during early initialization the stack_base() can return 0. | 6541 // Note: during early initialization the stack_base() can return 0. |
| 6678 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { | 6542 if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) { |
| 6679 ReportError("stack overflow while parsing"); | 6543 ReportError("stack overflow while parsing"); |
| 6680 } | 6544 } |
| 6681 } | 6545 } |
| 6682 | 6546 |
| 6683 | |
| 6684 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 6547 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
| 6685 Block* block = new (Z) Block(current_block_, outer_scope, | 6548 Block* block = new (Z) Block(current_block_, outer_scope, |
| 6686 new (Z) SequenceNode(TokenPos(), outer_scope)); | 6549 new (Z) SequenceNode(TokenPos(), outer_scope)); |
| 6687 current_block_ = block; | 6550 current_block_ = block; |
| 6688 } | 6551 } |
| 6689 | 6552 |
| 6690 | |
| 6691 void Parser::OpenBlock() { | 6553 void Parser::OpenBlock() { |
| 6692 ASSERT(current_block_ != NULL); | 6554 ASSERT(current_block_ != NULL); |
| 6693 LocalScope* outer_scope = current_block_->scope; | 6555 LocalScope* outer_scope = current_block_->scope; |
| 6694 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), | 6556 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), |
| 6695 outer_scope->loop_level())); | 6557 outer_scope->loop_level())); |
| 6696 } | 6558 } |
| 6697 | 6559 |
| 6698 | |
| 6699 void Parser::OpenLoopBlock() { | 6560 void Parser::OpenLoopBlock() { |
| 6700 ASSERT(current_block_ != NULL); | 6561 ASSERT(current_block_ != NULL); |
| 6701 LocalScope* outer_scope = current_block_->scope; | 6562 LocalScope* outer_scope = current_block_->scope; |
| 6702 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), | 6563 ChainNewBlock(new (Z) LocalScope(outer_scope, outer_scope->function_level(), |
| 6703 outer_scope->loop_level() + 1)); | 6564 outer_scope->loop_level() + 1)); |
| 6704 } | 6565 } |
| 6705 | 6566 |
| 6706 | |
| 6707 void Parser::OpenFunctionBlock(const Function& func) { | 6567 void Parser::OpenFunctionBlock(const Function& func) { |
| 6708 LocalScope* outer_scope; | 6568 LocalScope* outer_scope; |
| 6709 if (current_block_ == NULL) { | 6569 if (current_block_ == NULL) { |
| 6710 if (!func.IsLocalFunction()) { | 6570 if (!func.IsLocalFunction()) { |
| 6711 // We are compiling a non-nested function. | 6571 // We are compiling a non-nested function. |
| 6712 outer_scope = new (Z) LocalScope(NULL, 0, 0); | 6572 outer_scope = new (Z) LocalScope(NULL, 0, 0); |
| 6713 } else { | 6573 } else { |
| 6714 // We are compiling the function of an invoked closure. | 6574 // We are compiling the function of an invoked closure. |
| 6715 // Restore the outer scope containing all captured variables. | 6575 // Restore the outer scope containing all captured variables. |
| 6716 const ContextScope& context_scope = | 6576 const ContextScope& context_scope = |
| 6717 ContextScope::Handle(Z, func.context_scope()); | 6577 ContextScope::Handle(Z, func.context_scope()); |
| 6718 ASSERT(!context_scope.IsNull()); | 6578 ASSERT(!context_scope.IsNull()); |
| 6719 outer_scope = new (Z) | 6579 outer_scope = new (Z) |
| 6720 LocalScope(LocalScope::RestoreOuterScope(context_scope), 0, 0); | 6580 LocalScope(LocalScope::RestoreOuterScope(context_scope), 0, 0); |
| 6721 } | 6581 } |
| 6722 } else { | 6582 } else { |
| 6723 // We are parsing a nested function while compiling the enclosing function. | 6583 // We are parsing a nested function while compiling the enclosing function. |
| 6724 outer_scope = new (Z) LocalScope( | 6584 outer_scope = new (Z) LocalScope( |
| 6725 current_block_->scope, current_block_->scope->function_level() + 1, 0); | 6585 current_block_->scope, current_block_->scope->function_level() + 1, 0); |
| 6726 } | 6586 } |
| 6727 ChainNewBlock(outer_scope); | 6587 ChainNewBlock(outer_scope); |
| 6728 } | 6588 } |
| 6729 | 6589 |
| 6730 | |
| 6731 void Parser::OpenAsyncClosure() { | 6590 void Parser::OpenAsyncClosure() { |
| 6732 TRACE_PARSER("OpenAsyncClosure"); | 6591 TRACE_PARSER("OpenAsyncClosure"); |
| 6733 async_temp_scope_ = current_block_->scope; | 6592 async_temp_scope_ = current_block_->scope; |
| 6734 OpenAsyncTryBlock(); | 6593 OpenAsyncTryBlock(); |
| 6735 } | 6594 } |
| 6736 | 6595 |
| 6737 | |
| 6738 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode* body) { | 6596 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode* body) { |
| 6739 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); | 6597 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); |
| 6740 // The generated try-catch-finally that wraps the async generator function | 6598 // The generated try-catch-finally that wraps the async generator function |
| 6741 // body is the outermost try statement. | 6599 // body is the outermost try statement. |
| 6742 ASSERT(try_stack_ != NULL); | 6600 ASSERT(try_stack_ != NULL); |
| 6743 ASSERT(try_stack_->outer_try() == NULL); | 6601 ASSERT(try_stack_->outer_try() == NULL); |
| 6744 // We only get here when parsing an async generator body. | 6602 // We only get here when parsing an async generator body. |
| 6745 ASSERT(innermost_function().IsAsyncGenClosure()); | 6603 ASSERT(innermost_function().IsAsyncGenClosure()); |
| 6746 | 6604 |
| 6747 const TokenPosition try_end_pos = innermost_function().end_token_pos(); | 6605 const TokenPosition try_end_pos = innermost_function().end_token_pos(); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6883 | 6741 |
| 6884 const intptr_t try_index = try_statement->try_index(); | 6742 const intptr_t try_index = try_statement->try_index(); |
| 6885 | 6743 |
| 6886 AstNode* try_catch_node = new (Z) | 6744 AstNode* try_catch_node = new (Z) |
| 6887 TryCatchNode(TokenPosition::kNoSource, body, context_var, catch_clause, | 6745 TryCatchNode(TokenPosition::kNoSource, body, context_var, catch_clause, |
| 6888 finally_clause, try_index, finally_clause); | 6746 finally_clause, try_index, finally_clause); |
| 6889 current_block_->statements->Add(try_catch_node); | 6747 current_block_->statements->Add(try_catch_node); |
| 6890 return CloseBlock(); | 6748 return CloseBlock(); |
| 6891 } | 6749 } |
| 6892 | 6750 |
| 6893 | |
| 6894 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block, | 6751 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block, |
| 6895 TokenPosition func_end_pos) { | 6752 TokenPosition func_end_pos) { |
| 6896 // This is the outermost try-catch of the function. | 6753 // This is the outermost try-catch of the function. |
| 6897 ASSERT(try_stack_ != NULL); | 6754 ASSERT(try_stack_ != NULL); |
| 6898 ASSERT(try_stack_->outer_try() == NULL); | 6755 ASSERT(try_stack_->outer_try() == NULL); |
| 6899 ASSERT(innermost_function().IsAsyncClosure()); | 6756 ASSERT(innermost_function().IsAsyncClosure()); |
| 6900 LocalScope* try_scope = current_block_->scope; | 6757 LocalScope* try_scope = current_block_->scope; |
| 6901 | 6758 |
| 6902 try_stack_->enter_catch(); | 6759 try_stack_->enter_catch(); |
| 6903 | 6760 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6984 saved_stack_trace_var, CatchClauseNode::kInvalidTryIndex, true); | 6841 saved_stack_trace_var, CatchClauseNode::kInvalidTryIndex, true); |
| 6985 AstNode* try_catch_node = new (Z) TryCatchNode( | 6842 AstNode* try_catch_node = new (Z) TryCatchNode( |
| 6986 TokenPosition::kNoSource, try_block, context_var, catch_clause, | 6843 TokenPosition::kNoSource, try_block, context_var, catch_clause, |
| 6987 NULL, // No finally clause. | 6844 NULL, // No finally clause. |
| 6988 try_index, | 6845 try_index, |
| 6989 NULL); // No rethrow-finally clause. | 6846 NULL); // No rethrow-finally clause. |
| 6990 current_block_->statements->Add(try_catch_node); | 6847 current_block_->statements->Add(try_catch_node); |
| 6991 return CloseBlock(); | 6848 return CloseBlock(); |
| 6992 } | 6849 } |
| 6993 | 6850 |
| 6994 | |
| 6995 // Wrap the body of the async or async* closure in a try/catch block. | 6851 // Wrap the body of the async or async* closure in a try/catch block. |
| 6996 void Parser::OpenAsyncTryBlock() { | 6852 void Parser::OpenAsyncTryBlock() { |
| 6997 ASSERT(innermost_function().IsAsyncClosure() || | 6853 ASSERT(innermost_function().IsAsyncClosure() || |
| 6998 innermost_function().IsAsyncGenClosure()); | 6854 innermost_function().IsAsyncGenClosure()); |
| 6999 LocalVariable* context_var = NULL; | 6855 LocalVariable* context_var = NULL; |
| 7000 LocalVariable* exception_var = NULL; | 6856 LocalVariable* exception_var = NULL; |
| 7001 LocalVariable* stack_trace_var = NULL; | 6857 LocalVariable* stack_trace_var = NULL; |
| 7002 LocalVariable* saved_exception_var = NULL; | 6858 LocalVariable* saved_exception_var = NULL; |
| 7003 LocalVariable* saved_stack_trace_var = NULL; | 6859 LocalVariable* saved_stack_trace_var = NULL; |
| 7004 SetupExceptionVariables(current_block_->scope, true, &context_var, | 6860 SetupExceptionVariables(current_block_->scope, true, &context_var, |
| 7005 &exception_var, &stack_trace_var, | 6861 &exception_var, &stack_trace_var, |
| 7006 &saved_exception_var, &saved_stack_trace_var); | 6862 &saved_exception_var, &saved_stack_trace_var); |
| 7007 | 6863 |
| 7008 // Open the try block. | 6864 // Open the try block. |
| 7009 OpenBlock(); | 6865 OpenBlock(); |
| 7010 // This is the outermost try-catch in the function. | 6866 // This is the outermost try-catch in the function. |
| 7011 ASSERT(try_stack_ == NULL); | 6867 ASSERT(try_stack_ == NULL); |
| 7012 PushTry(current_block_); | 6868 PushTry(current_block_); |
| 7013 // Validate that we always get try index of 0. | 6869 // Validate that we always get try index of 0. |
| 7014 ASSERT(try_stack_->try_index() == CatchClauseNode::kImplicitAsyncTryIndex); | 6870 ASSERT(try_stack_->try_index() == CatchClauseNode::kImplicitAsyncTryIndex); |
| 7015 | 6871 |
| 7016 SetupSavedTryContext(context_var); | 6872 SetupSavedTryContext(context_var); |
| 7017 } | 6873 } |
| 7018 | 6874 |
| 7019 | |
| 7020 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6875 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
| 7021 // Create the parameter list for the body closure of a sync generator: | 6876 // Create the parameter list for the body closure of a sync generator: |
| 7022 // 1) Implicit closure parameter; | 6877 // 1) Implicit closure parameter; |
| 7023 // 2) Iterator | 6878 // 2) Iterator |
| 7024 // Add implicit closure parameter if not already present. | 6879 // Add implicit closure parameter if not already present. |
| 7025 if (params->parameters->length() == 0) { | 6880 if (params->parameters->length() == 0) { |
| 7026 params->AddFinalParameter(TokenPosition::kMinSource, | 6881 params->AddFinalParameter(TokenPosition::kMinSource, |
| 7027 &Symbols::ClosureParameter(), | 6882 &Symbols::ClosureParameter(), |
| 7028 &Object::dynamic_type()); | 6883 &Object::dynamic_type()); |
| 7029 } | 6884 } |
| 7030 ParamDesc iterator_param; | 6885 ParamDesc iterator_param; |
| 7031 iterator_param.name = &Symbols::IteratorParameter(); | 6886 iterator_param.name = &Symbols::IteratorParameter(); |
| 7032 iterator_param.type = &Object::dynamic_type(); | 6887 iterator_param.type = &Object::dynamic_type(); |
| 7033 params->parameters->Add(iterator_param); | 6888 params->parameters->Add(iterator_param); |
| 7034 params->num_fixed_parameters++; | 6889 params->num_fixed_parameters++; |
| 7035 } | 6890 } |
| 7036 | 6891 |
| 7037 | |
| 7038 void Parser::AddAsyncGenClosureParameters(ParamList* params) { | 6892 void Parser::AddAsyncGenClosureParameters(ParamList* params) { |
| 7039 // Create the parameter list for the body closure of an async generator. | 6893 // Create the parameter list for the body closure of an async generator. |
| 7040 // The closure has the same parameters as an asynchronous non-generator. | 6894 // The closure has the same parameters as an asynchronous non-generator. |
| 7041 AddAsyncClosureParameters(params); | 6895 AddAsyncClosureParameters(params); |
| 7042 } | 6896 } |
| 7043 | 6897 |
| 7044 | |
| 7045 RawFunction* Parser::OpenSyncGeneratorFunction(TokenPosition func_pos) { | 6898 RawFunction* Parser::OpenSyncGeneratorFunction(TokenPosition func_pos) { |
| 7046 Function& body = Function::Handle(Z); | 6899 Function& body = Function::Handle(Z); |
| 7047 String& body_closure_name = String::Handle(Z); | 6900 String& body_closure_name = String::Handle(Z); |
| 7048 bool is_new_closure = false; | 6901 bool is_new_closure = false; |
| 7049 | 6902 |
| 7050 AddContinuationVariables(); | 6903 AddContinuationVariables(); |
| 7051 | 6904 |
| 7052 // Check whether a function for the body of this generator | 6905 // Check whether a function for the body of this generator |
| 7053 // function has already been created by a previous | 6906 // function has already been created by a previous |
| 7054 // compilation. | 6907 // compilation. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7130 arguments->Add(closure_obj); | 6983 arguments->Add(closure_obj); |
| 7131 ConstructorCallNode* new_iterable = new (Z) ConstructorCallNode( | 6984 ConstructorCallNode* new_iterable = new (Z) ConstructorCallNode( |
| 7132 TokenPosition::kNoSource, TypeArguments::ZoneHandle(Z), | 6985 TokenPosition::kNoSource, TypeArguments::ZoneHandle(Z), |
| 7133 iterable_constructor, arguments); | 6986 iterable_constructor, arguments); |
| 7134 ReturnNode* return_node = | 6987 ReturnNode* return_node = |
| 7135 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); | 6988 new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable); |
| 7136 current_block_->statements->Add(return_node); | 6989 current_block_->statements->Add(return_node); |
| 7137 return CloseBlock(); | 6990 return CloseBlock(); |
| 7138 } | 6991 } |
| 7139 | 6992 |
| 7140 | |
| 7141 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6993 void Parser::AddAsyncClosureParameters(ParamList* params) { |
| 7142 // Async closures have three optional parameters: | 6994 // Async closures have three optional parameters: |
| 7143 // * A continuation result. | 6995 // * A continuation result. |
| 7144 // * A continuation error. | 6996 // * A continuation error. |
| 7145 // * A continuation stack trace. | 6997 // * A continuation stack trace. |
| 7146 ASSERT(params->parameters->length() <= 1); | 6998 ASSERT(params->parameters->length() <= 1); |
| 7147 // Add implicit closure parameter if not yet present. | 6999 // Add implicit closure parameter if not yet present. |
| 7148 if (params->parameters->length() == 0) { | 7000 if (params->parameters->length() == 0) { |
| 7149 params->AddFinalParameter(TokenPosition::kMinSource, | 7001 params->AddFinalParameter(TokenPosition::kMinSource, |
| 7150 &Symbols::ClosureParameter(), | 7002 &Symbols::ClosureParameter(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 7162 params->parameters->Add(error_param); | 7014 params->parameters->Add(error_param); |
| 7163 ParamDesc stack_trace_param; | 7015 ParamDesc stack_trace_param; |
| 7164 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | 7016 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); |
| 7165 stack_trace_param.default_value = &Object::null_instance(); | 7017 stack_trace_param.default_value = &Object::null_instance(); |
| 7166 stack_trace_param.type = &Object::dynamic_type(); | 7018 stack_trace_param.type = &Object::dynamic_type(); |
| 7167 params->parameters->Add(stack_trace_param); | 7019 params->parameters->Add(stack_trace_param); |
| 7168 params->has_optional_positional_parameters = true; | 7020 params->has_optional_positional_parameters = true; |
| 7169 params->num_optional_parameters += 3; | 7021 params->num_optional_parameters += 3; |
| 7170 } | 7022 } |
| 7171 | 7023 |
| 7172 | |
| 7173 RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) { | 7024 RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) { |
| 7174 TRACE_PARSER("OpenAsyncFunction"); | 7025 TRACE_PARSER("OpenAsyncFunction"); |
| 7175 AddContinuationVariables(); | 7026 AddContinuationVariables(); |
| 7176 AddAsyncClosureVariables(); | 7027 AddAsyncClosureVariables(); |
| 7177 Function& closure = Function::Handle(Z); | 7028 Function& closure = Function::Handle(Z); |
| 7178 bool is_new_closure = false; | 7029 bool is_new_closure = false; |
| 7179 | 7030 |
| 7180 // Check whether a function for the asynchronous function body of | 7031 // Check whether a function for the asynchronous function body of |
| 7181 // this async function has already been created by a previous | 7032 // this async function has already been created by a previous |
| 7182 // compilation of this function. | 7033 // compilation of this function. |
| (...skipping 30 matching lines...) Expand all Loading... |
| 7213 closure.SetSignatureType(signature_type); | 7064 closure.SetSignatureType(signature_type); |
| 7214 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); | 7065 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); |
| 7215 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 7066 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
| 7216 } | 7067 } |
| 7217 OpenFunctionBlock(closure); | 7068 OpenFunctionBlock(closure); |
| 7218 AddFormalParamsToScope(&closure_params, current_block_->scope); | 7069 AddFormalParamsToScope(&closure_params, current_block_->scope); |
| 7219 async_temp_scope_ = current_block_->scope; | 7070 async_temp_scope_ = current_block_->scope; |
| 7220 return closure.raw(); | 7071 return closure.raw(); |
| 7221 } | 7072 } |
| 7222 | 7073 |
| 7223 | |
| 7224 void Parser::AddContinuationVariables() { | 7074 void Parser::AddContinuationVariables() { |
| 7225 // Add to current block's scope: | 7075 // Add to current block's scope: |
| 7226 // var :await_jump_var; | 7076 // var :await_jump_var; |
| 7227 // var :await_ctx_var; | 7077 // var :await_ctx_var; |
| 7228 LocalVariable* await_jump_var = | 7078 LocalVariable* await_jump_var = |
| 7229 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7079 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7230 Symbols::AwaitJumpVar(), Object::dynamic_type()); | 7080 Symbols::AwaitJumpVar(), Object::dynamic_type()); |
| 7231 current_block_->scope->AddVariable(await_jump_var); | 7081 current_block_->scope->AddVariable(await_jump_var); |
| 7232 LocalVariable* await_ctx_var = | 7082 LocalVariable* await_ctx_var = |
| 7233 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7083 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7234 Symbols::AwaitContextVar(), Object::dynamic_type()); | 7084 Symbols::AwaitContextVar(), Object::dynamic_type()); |
| 7235 current_block_->scope->AddVariable(await_ctx_var); | 7085 current_block_->scope->AddVariable(await_ctx_var); |
| 7236 } | 7086 } |
| 7237 | 7087 |
| 7238 | |
| 7239 void Parser::AddAsyncClosureVariables() { | 7088 void Parser::AddAsyncClosureVariables() { |
| 7240 // Add to current block's scope: | 7089 // Add to current block's scope: |
| 7241 // var :async_op; | 7090 // var :async_op; |
| 7242 // var :async_then_callback; | 7091 // var :async_then_callback; |
| 7243 // var :async_catch_error_callback; | 7092 // var :async_catch_error_callback; |
| 7244 // var :async_completer; | 7093 // var :async_completer; |
| 7245 // var :async_stack_trace; | 7094 // var :async_stack_trace; |
| 7246 LocalVariable* async_op_var = | 7095 LocalVariable* async_op_var = |
| 7247 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7096 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7248 Symbols::AsyncOperation(), Object::dynamic_type()); | 7097 Symbols::AsyncOperation(), Object::dynamic_type()); |
| 7249 current_block_->scope->AddVariable(async_op_var); | 7098 current_block_->scope->AddVariable(async_op_var); |
| 7250 LocalVariable* async_then_callback_var = new (Z) | 7099 LocalVariable* async_then_callback_var = new (Z) |
| 7251 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7100 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7252 Symbols::AsyncThenCallback(), Object::dynamic_type()); | 7101 Symbols::AsyncThenCallback(), Object::dynamic_type()); |
| 7253 current_block_->scope->AddVariable(async_then_callback_var); | 7102 current_block_->scope->AddVariable(async_then_callback_var); |
| 7254 LocalVariable* async_catch_error_callback_var = new (Z) | 7103 LocalVariable* async_catch_error_callback_var = new (Z) |
| 7255 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7104 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7256 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); | 7105 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); |
| 7257 current_block_->scope->AddVariable(async_catch_error_callback_var); | 7106 current_block_->scope->AddVariable(async_catch_error_callback_var); |
| 7258 LocalVariable* async_completer = | 7107 LocalVariable* async_completer = |
| 7259 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7108 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7260 Symbols::AsyncCompleter(), Object::dynamic_type()); | 7109 Symbols::AsyncCompleter(), Object::dynamic_type()); |
| 7261 current_block_->scope->AddVariable(async_completer); | 7110 current_block_->scope->AddVariable(async_completer); |
| 7262 LocalVariable* async_stack_trace = new (Z) | 7111 LocalVariable* async_stack_trace = new (Z) |
| 7263 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7112 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7264 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); | 7113 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); |
| 7265 current_block_->scope->AddVariable(async_stack_trace); | 7114 current_block_->scope->AddVariable(async_stack_trace); |
| 7266 } | 7115 } |
| 7267 | 7116 |
| 7268 | |
| 7269 void Parser::AddAsyncGeneratorVariables() { | 7117 void Parser::AddAsyncGeneratorVariables() { |
| 7270 // Add to current block's scope: | 7118 // Add to current block's scope: |
| 7271 // var :controller; | 7119 // var :controller; |
| 7272 // The :controller variable is used by the async generator closure to | 7120 // The :controller variable is used by the async generator closure to |
| 7273 // store the StreamController object to which the yielded expressions | 7121 // store the StreamController object to which the yielded expressions |
| 7274 // are added. | 7122 // are added. |
| 7275 // var :async_op; | 7123 // var :async_op; |
| 7276 // var :async_then_callback; | 7124 // var :async_then_callback; |
| 7277 // var :async_catch_error_callback; | 7125 // var :async_catch_error_callback; |
| 7278 // var :async_stack_trace; | 7126 // var :async_stack_trace; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7298 LocalVariable* async_stack_trace = new (Z) | 7146 LocalVariable* async_stack_trace = new (Z) |
| 7299 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7147 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7300 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); | 7148 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); |
| 7301 current_block_->scope->AddVariable(async_stack_trace); | 7149 current_block_->scope->AddVariable(async_stack_trace); |
| 7302 LocalVariable* controller_stream = new (Z) | 7150 LocalVariable* controller_stream = new (Z) |
| 7303 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7151 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7304 Symbols::ControllerStream(), Object::dynamic_type()); | 7152 Symbols::ControllerStream(), Object::dynamic_type()); |
| 7305 current_block_->scope->AddVariable(controller_stream); | 7153 current_block_->scope->AddVariable(controller_stream); |
| 7306 } | 7154 } |
| 7307 | 7155 |
| 7308 | |
| 7309 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { | 7156 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { |
| 7310 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 7157 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
| 7311 AddContinuationVariables(); | 7158 AddContinuationVariables(); |
| 7312 AddAsyncGeneratorVariables(); | 7159 AddAsyncGeneratorVariables(); |
| 7313 | 7160 |
| 7314 Function& closure = Function::Handle(Z); | 7161 Function& closure = Function::Handle(Z); |
| 7315 bool is_new_closure = false; | 7162 bool is_new_closure = false; |
| 7316 | 7163 |
| 7317 // Check whether a function for the asynchronous function body of | 7164 // Check whether a function for the asynchronous function body of |
| 7318 // this async generator has already been created by a previous | 7165 // this async generator has already been created by a previous |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7352 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); | 7199 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); |
| 7353 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 7200 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
| 7354 } | 7201 } |
| 7355 | 7202 |
| 7356 OpenFunctionBlock(closure); | 7203 OpenFunctionBlock(closure); |
| 7357 AddFormalParamsToScope(&closure_params, current_block_->scope); | 7204 AddFormalParamsToScope(&closure_params, current_block_->scope); |
| 7358 async_temp_scope_ = current_block_->scope; | 7205 async_temp_scope_ = current_block_->scope; |
| 7359 return closure.raw(); | 7206 return closure.raw(); |
| 7360 } | 7207 } |
| 7361 | 7208 |
| 7362 | |
| 7363 // Generate the Ast nodes for the implicit code of the async* function. | 7209 // Generate the Ast nodes for the implicit code of the async* function. |
| 7364 // | 7210 // |
| 7365 // f(...) async* { | 7211 // f(...) async* { |
| 7366 // var :controller; | 7212 // var :controller; |
| 7367 // var :await_jump_var = -1; | 7213 // var :await_jump_var = -1; |
| 7368 // var :await_context_var; | 7214 // var :await_context_var; |
| 7369 // f_async_body() { | 7215 // f_async_body() { |
| 7370 // ... source code of f ... | 7216 // ... source code of f ... |
| 7371 // } | 7217 // } |
| 7372 // var :async_op = f_async_body; | 7218 // var :async_op = f_async_body; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7422 // :await_jump_var = -1; | 7268 // :await_jump_var = -1; |
| 7423 LocalVariable* jump_var = | 7269 LocalVariable* jump_var = |
| 7424 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 7270 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 7425 LiteralNode* init_value = new (Z) | 7271 LiteralNode* init_value = new (Z) |
| 7426 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); | 7272 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); |
| 7427 current_block_->statements->Add( | 7273 current_block_->statements->Add( |
| 7428 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); | 7274 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); |
| 7429 | 7275 |
| 7430 TokenPosition token_pos = TokenPosition::kNoSource; | 7276 TokenPosition token_pos = TokenPosition::kNoSource; |
| 7431 | 7277 |
| 7432 | |
| 7433 // Add to AST: | 7278 // Add to AST: |
| 7434 // :async_op = <closure>; (containing the original body) | 7279 // :async_op = <closure>; (containing the original body) |
| 7435 LocalVariable* async_op_var = | 7280 LocalVariable* async_op_var = |
| 7436 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 7281 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
| 7437 ClosureNode* closure_obj = new (Z) ClosureNode( | 7282 ClosureNode* closure_obj = new (Z) ClosureNode( |
| 7438 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); | 7283 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); |
| 7439 StoreLocalNode* store_async_op = new (Z) | 7284 StoreLocalNode* store_async_op = new (Z) |
| 7440 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj); | 7285 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj); |
| 7441 | 7286 |
| 7442 current_block_->statements->Add(store_async_op); | 7287 current_block_->statements->Add(store_async_op); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7537 current_block_->statements->Add(store_controller_stream); | 7382 current_block_->statements->Add(store_controller_stream); |
| 7538 | 7383 |
| 7539 // return :controller.stream; | 7384 // return :controller.stream; |
| 7540 ReturnNode* return_node = new (Z) ReturnNode( | 7385 ReturnNode* return_node = new (Z) ReturnNode( |
| 7541 TokenPosition::kNoSource, | 7386 TokenPosition::kNoSource, |
| 7542 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var)); | 7387 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var)); |
| 7543 current_block_->statements->Add(return_node); | 7388 current_block_->statements->Add(return_node); |
| 7544 return CloseBlock(); | 7389 return CloseBlock(); |
| 7545 } | 7390 } |
| 7546 | 7391 |
| 7547 | |
| 7548 void Parser::OpenAsyncGeneratorClosure() { | 7392 void Parser::OpenAsyncGeneratorClosure() { |
| 7549 async_temp_scope_ = current_block_->scope; | 7393 async_temp_scope_ = current_block_->scope; |
| 7550 OpenAsyncTryBlock(); | 7394 OpenAsyncTryBlock(); |
| 7551 } | 7395 } |
| 7552 | 7396 |
| 7553 | |
| 7554 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { | 7397 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { |
| 7555 // We need a temporary expression to store intermediate return values. | 7398 // We need a temporary expression to store intermediate return values. |
| 7556 parsed_function()->EnsureExpressionTemp(); | 7399 parsed_function()->EnsureExpressionTemp(); |
| 7557 | 7400 |
| 7558 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); | 7401 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); |
| 7559 ASSERT(new_body != NULL); | 7402 ASSERT(new_body != NULL); |
| 7560 ASSERT(new_body->scope() != NULL); | 7403 ASSERT(new_body->scope() != NULL); |
| 7561 return new_body; | 7404 return new_body; |
| 7562 } | 7405 } |
| 7563 | 7406 |
| 7564 | |
| 7565 // Add a return node to the sequence if necessary. | 7407 // Add a return node to the sequence if necessary. |
| 7566 void Parser::EnsureHasReturnStatement(SequenceNode* seq, | 7408 void Parser::EnsureHasReturnStatement(SequenceNode* seq, |
| 7567 TokenPosition return_pos) { | 7409 TokenPosition return_pos) { |
| 7568 if ((seq->length() == 0) || !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { | 7410 if ((seq->length() == 0) || !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { |
| 7569 const Function& func = innermost_function(); | 7411 const Function& func = innermost_function(); |
| 7570 // The implicit return value of synchronous generator closures is false, | 7412 // The implicit return value of synchronous generator closures is false, |
| 7571 // to indicate that there are no more elements in the iterable. | 7413 // to indicate that there are no more elements in the iterable. |
| 7572 // In other cases the implicit return value is null. | 7414 // In other cases the implicit return value is null. |
| 7573 AstNode* return_value = | 7415 AstNode* return_value = |
| 7574 func.IsSyncGenClosure() | 7416 func.IsSyncGenClosure() |
| 7575 ? new LiteralNode(return_pos, Bool::False()) | 7417 ? new LiteralNode(return_pos, Bool::False()) |
| 7576 : new LiteralNode(return_pos, Instance::ZoneHandle()); | 7418 : new LiteralNode(return_pos, Instance::ZoneHandle()); |
| 7577 seq->Add(new ReturnNode(return_pos, return_value)); | 7419 seq->Add(new ReturnNode(return_pos, return_value)); |
| 7578 } | 7420 } |
| 7579 } | 7421 } |
| 7580 | 7422 |
| 7581 | |
| 7582 SequenceNode* Parser::CloseBlock() { | 7423 SequenceNode* Parser::CloseBlock() { |
| 7583 SequenceNode* statements = current_block_->statements; | 7424 SequenceNode* statements = current_block_->statements; |
| 7584 if (current_block_->scope != NULL) { | 7425 if (current_block_->scope != NULL) { |
| 7585 // Record the begin and end token index of the scope. | 7426 // Record the begin and end token index of the scope. |
| 7586 ASSERT(statements != NULL); | 7427 ASSERT(statements != NULL); |
| 7587 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 7428 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
| 7588 current_block_->scope->set_end_token_pos(TokenPos()); | 7429 current_block_->scope->set_end_token_pos(TokenPos()); |
| 7589 } | 7430 } |
| 7590 current_block_ = current_block_->parent; | 7431 current_block_ = current_block_->parent; |
| 7591 return statements; | 7432 return statements; |
| 7592 } | 7433 } |
| 7593 | 7434 |
| 7594 | |
| 7595 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, | 7435 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, |
| 7596 SequenceNode* closure_body) { | 7436 SequenceNode* closure_body) { |
| 7597 TRACE_PARSER("CloseAsyncFunction"); | 7437 TRACE_PARSER("CloseAsyncFunction"); |
| 7598 ASSERT(!closure.IsNull()); | 7438 ASSERT(!closure.IsNull()); |
| 7599 ASSERT(closure_body != NULL); | 7439 ASSERT(closure_body != NULL); |
| 7600 | 7440 |
| 7601 // Explicitly reference variables of the async function from the | 7441 // Explicitly reference variables of the async function from the |
| 7602 // closure body in order to mark them as captured. | 7442 // closure body in order to mark them as captured. |
| 7603 LocalVariable* existing_var = | 7443 LocalVariable* existing_var = |
| 7604 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 7444 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7737 // return :async_completer.future; | 7577 // return :async_completer.future; |
| 7738 ReturnNode* return_node = new (Z) ReturnNode( | 7578 ReturnNode* return_node = new (Z) ReturnNode( |
| 7739 token_pos, | 7579 token_pos, |
| 7740 new (Z) InstanceGetterNode( | 7580 new (Z) InstanceGetterNode( |
| 7741 token_pos, new (Z) LoadLocalNode(token_pos, async_completer), | 7581 token_pos, new (Z) LoadLocalNode(token_pos, async_completer), |
| 7742 Symbols::CompleterFuture())); | 7582 Symbols::CompleterFuture())); |
| 7743 current_block_->statements->Add(return_node); | 7583 current_block_->statements->Add(return_node); |
| 7744 return CloseBlock(); | 7584 return CloseBlock(); |
| 7745 } | 7585 } |
| 7746 | 7586 |
| 7747 | |
| 7748 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body, | 7587 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body, |
| 7749 TokenPosition func_end_pos) { | 7588 TokenPosition func_end_pos) { |
| 7750 // We need a temporary expression to store intermediate return values. | 7589 // We need a temporary expression to store intermediate return values. |
| 7751 parsed_function()->EnsureExpressionTemp(); | 7590 parsed_function()->EnsureExpressionTemp(); |
| 7752 | 7591 |
| 7753 SequenceNode* new_body = CloseAsyncTryBlock(body, func_end_pos); | 7592 SequenceNode* new_body = CloseAsyncTryBlock(body, func_end_pos); |
| 7754 ASSERT(new_body != NULL); | 7593 ASSERT(new_body != NULL); |
| 7755 ASSERT(new_body->scope() != NULL); | 7594 ASSERT(new_body->scope() != NULL); |
| 7756 return new_body; | 7595 return new_body; |
| 7757 } | 7596 } |
| 7758 | 7597 |
| 7759 | |
| 7760 // Set up default values for all optional parameters to the function. | 7598 // Set up default values for all optional parameters to the function. |
| 7761 void Parser::SetupDefaultsForOptionalParams(const ParamList& params) { | 7599 void Parser::SetupDefaultsForOptionalParams(const ParamList& params) { |
| 7762 if ((current_function().raw() == innermost_function().raw()) && | 7600 if ((current_function().raw() == innermost_function().raw()) && |
| 7763 (params.num_optional_parameters > 0)) { | 7601 (params.num_optional_parameters > 0)) { |
| 7764 ZoneGrowableArray<const Instance*>* default_values = | 7602 ZoneGrowableArray<const Instance*>* default_values = |
| 7765 new ZoneGrowableArray<const Instance*>(zone(), | 7603 new ZoneGrowableArray<const Instance*>(zone(), |
| 7766 params.num_optional_parameters); | 7604 params.num_optional_parameters); |
| 7767 // Build array of default parameter values. | 7605 // Build array of default parameter values. |
| 7768 const ZoneGrowableArray<ParamDesc>& parameters = *params.parameters; | 7606 const ZoneGrowableArray<ParamDesc>& parameters = *params.parameters; |
| 7769 const int first_opt_param_offset = params.num_fixed_parameters; | 7607 const int first_opt_param_offset = params.num_fixed_parameters; |
| 7770 for (int i = 0; i < params.num_optional_parameters; i++) { | 7608 for (int i = 0; i < params.num_optional_parameters; i++) { |
| 7771 const Instance* default_value = | 7609 const Instance* default_value = |
| 7772 parameters[i + first_opt_param_offset].default_value; | 7610 parameters[i + first_opt_param_offset].default_value; |
| 7773 default_values->Add(default_value); | 7611 default_values->Add(default_value); |
| 7774 } | 7612 } |
| 7775 parsed_function()->set_default_parameter_values(default_values); | 7613 parsed_function()->set_default_parameter_values(default_values); |
| 7776 } | 7614 } |
| 7777 } | 7615 } |
| 7778 | 7616 |
| 7779 | |
| 7780 void Parser::FinalizeFormalParameterTypes(const ParamList* params) { | 7617 void Parser::FinalizeFormalParameterTypes(const ParamList* params) { |
| 7781 ASSERT((params != NULL) && (params->parameters != NULL)); | 7618 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 7782 const int num_parameters = params->parameters->length(); | 7619 const int num_parameters = params->parameters->length(); |
| 7783 AbstractType& type = AbstractType::Handle(Z); | 7620 AbstractType& type = AbstractType::Handle(Z); |
| 7784 for (int i = 0; i < num_parameters; i++) { | 7621 for (int i = 0; i < num_parameters; i++) { |
| 7785 ParamDesc& param_desc = (*params->parameters)[i]; | 7622 ParamDesc& param_desc = (*params->parameters)[i]; |
| 7786 type = param_desc.type->raw(); | 7623 type = param_desc.type->raw(); |
| 7787 ResolveType(&type); | 7624 ResolveType(&type); |
| 7788 type = CanonicalizeType(type); | 7625 type = CanonicalizeType(type); |
| 7789 if (type.raw() != param_desc.type->raw()) { | 7626 if (type.raw() != param_desc.type->raw()) { |
| 7790 param_desc.type = &AbstractType::ZoneHandle(Z, type.raw()); | 7627 param_desc.type = &AbstractType::ZoneHandle(Z, type.raw()); |
| 7791 } | 7628 } |
| 7792 } | 7629 } |
| 7793 } | 7630 } |
| 7794 | 7631 |
| 7795 | |
| 7796 // Populate the parameter type array and parameter name array of the function | 7632 // Populate the parameter type array and parameter name array of the function |
| 7797 // with the formal parameter types and names. | 7633 // with the formal parameter types and names. |
| 7798 void Parser::AddFormalParamsToFunction(const ParamList* params, | 7634 void Parser::AddFormalParamsToFunction(const ParamList* params, |
| 7799 const Function& func) { | 7635 const Function& func) { |
| 7800 ASSERT((params != NULL) && (params->parameters != NULL)); | 7636 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 7801 ASSERT((params->num_optional_parameters > 0) == | 7637 ASSERT((params->num_optional_parameters > 0) == |
| 7802 (params->has_optional_positional_parameters || | 7638 (params->has_optional_positional_parameters || |
| 7803 params->has_optional_named_parameters)); | 7639 params->has_optional_named_parameters)); |
| 7804 if (!Utils::IsInt(16, params->num_fixed_parameters) || | 7640 if (!Utils::IsInt(16, params->num_fixed_parameters) || |
| 7805 !Utils::IsInt(16, params->num_optional_parameters)) { | 7641 !Utils::IsInt(16, params->num_optional_parameters)) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 7831 if (param_desc.is_covariant) { | 7667 if (param_desc.is_covariant) { |
| 7832 if (!func.IsDynamicFunction(true)) { | 7668 if (!func.IsDynamicFunction(true)) { |
| 7833 ReportError(param_desc.name_pos, | 7669 ReportError(param_desc.name_pos, |
| 7834 "only instance functions may have " | 7670 "only instance functions may have " |
| 7835 "covariant parameters"); | 7671 "covariant parameters"); |
| 7836 } | 7672 } |
| 7837 } | 7673 } |
| 7838 } | 7674 } |
| 7839 } | 7675 } |
| 7840 | 7676 |
| 7841 | |
| 7842 // Populate local scope with the formal parameters. | 7677 // Populate local scope with the formal parameters. |
| 7843 void Parser::AddFormalParamsToScope(const ParamList* params, | 7678 void Parser::AddFormalParamsToScope(const ParamList* params, |
| 7844 LocalScope* scope) { | 7679 LocalScope* scope) { |
| 7845 ASSERT((params != NULL) && (params->parameters != NULL)); | 7680 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 7846 ASSERT(scope != NULL); | 7681 ASSERT(scope != NULL); |
| 7847 const int num_parameters = params->parameters->length(); | 7682 const int num_parameters = params->parameters->length(); |
| 7848 for (int i = 0; i < num_parameters; i++) { | 7683 for (int i = 0; i < num_parameters; i++) { |
| 7849 ParamDesc& param_desc = (*params->parameters)[i]; | 7684 ParamDesc& param_desc = (*params->parameters)[i]; |
| 7850 const String* name = param_desc.name; | 7685 const String* name = param_desc.name; |
| 7851 LocalVariable* parameter = new (Z) LocalVariable( | 7686 LocalVariable* parameter = new (Z) LocalVariable( |
| 7852 param_desc.name_pos, param_desc.name_pos, *name, *param_desc.type); | 7687 param_desc.name_pos, param_desc.name_pos, *name, *param_desc.type); |
| 7853 if (!scope->InsertParameterAt(i, parameter)) { | 7688 if (!scope->InsertParameterAt(i, parameter)) { |
| 7854 ReportError(param_desc.name_pos, "name '%s' already exists in scope", | 7689 ReportError(param_desc.name_pos, "name '%s' already exists in scope", |
| 7855 param_desc.name->ToCString()); | 7690 param_desc.name->ToCString()); |
| 7856 } | 7691 } |
| 7857 param_desc.var = parameter; | 7692 param_desc.var = parameter; |
| 7858 if (param_desc.is_final) { | 7693 if (param_desc.is_final) { |
| 7859 parameter->set_is_final(); | 7694 parameter->set_is_final(); |
| 7860 } | 7695 } |
| 7861 if (FLAG_initializing_formal_access) { | 7696 if (FLAG_initializing_formal_access) { |
| 7862 // Field initializer parameters are implicitly final. | 7697 // Field initializer parameters are implicitly final. |
| 7863 ASSERT(!param_desc.is_field_initializer || param_desc.is_final); | 7698 ASSERT(!param_desc.is_field_initializer || param_desc.is_final); |
| 7864 } else if (param_desc.is_field_initializer) { | 7699 } else if (param_desc.is_field_initializer) { |
| 7865 parameter->set_invisible(true); | 7700 parameter->set_invisible(true); |
| 7866 } | 7701 } |
| 7867 } | 7702 } |
| 7868 } | 7703 } |
| 7869 | 7704 |
| 7870 | |
| 7871 // Builds ReturnNode/NativeBodyNode for a native function. | 7705 // Builds ReturnNode/NativeBodyNode for a native function. |
| 7872 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 7706 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 7873 const Function& func) { | 7707 const Function& func) { |
| 7874 ASSERT(func.is_native()); | 7708 ASSERT(func.is_native()); |
| 7875 ASSERT(func.NumParameters() == params->parameters->length()); | 7709 ASSERT(func.NumParameters() == params->parameters->length()); |
| 7876 TRACE_PARSER("ParseNativeFunctionBlock"); | 7710 TRACE_PARSER("ParseNativeFunctionBlock"); |
| 7877 | 7711 |
| 7878 // Parse the function name out. | 7712 // Parse the function name out. |
| 7879 const String& native_name = ParseNativeDeclaration(); | 7713 const String& native_name = ParseNativeDeclaration(); |
| 7880 | 7714 |
| 7881 // Now add the NativeBodyNode and return statement. | 7715 // Now add the NativeBodyNode and return statement. |
| 7882 current_block_->statements->Add(new (Z) ReturnNode( | 7716 current_block_->statements->Add(new (Z) ReturnNode( |
| 7883 TokenPos(), | 7717 TokenPos(), |
| 7884 new (Z) NativeBodyNode(TokenPos(), Function::ZoneHandle(Z, func.raw()), | 7718 new (Z) NativeBodyNode(TokenPos(), Function::ZoneHandle(Z, func.raw()), |
| 7885 native_name, current_block_->scope, | 7719 native_name, current_block_->scope, |
| 7886 FLAG_link_natives_lazily))); | 7720 FLAG_link_natives_lazily))); |
| 7887 } | 7721 } |
| 7888 | 7722 |
| 7889 | |
| 7890 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 7723 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| 7891 ASSERT(!current_function().is_static()); | 7724 ASSERT(!current_function().is_static()); |
| 7892 return from_scope->LookupVariable(Symbols::This(), test_only); | 7725 return from_scope->LookupVariable(Symbols::This(), test_only); |
| 7893 } | 7726 } |
| 7894 | 7727 |
| 7895 | |
| 7896 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, | 7728 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, |
| 7897 bool test_only) { | 7729 bool test_only) { |
| 7898 ASSERT(current_function().IsInFactoryScope()); | 7730 ASSERT(current_function().IsInFactoryScope()); |
| 7899 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), | 7731 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), |
| 7900 test_only); | 7732 test_only); |
| 7901 } | 7733 } |
| 7902 | 7734 |
| 7903 | |
| 7904 void Parser::CaptureInstantiator() { | 7735 void Parser::CaptureInstantiator() { |
| 7905 ASSERT(FunctionLevel() > 0); | 7736 ASSERT(FunctionLevel() > 0); |
| 7906 const String* variable_name = current_function().IsInFactoryScope() | 7737 const String* variable_name = current_function().IsInFactoryScope() |
| 7907 ? &Symbols::TypeArgumentsParameter() | 7738 ? &Symbols::TypeArgumentsParameter() |
| 7908 : &Symbols::This(); | 7739 : &Symbols::This(); |
| 7909 current_block_->scope->CaptureVariable( | 7740 current_block_->scope->CaptureVariable( |
| 7910 current_block_->scope->LookupVariable(*variable_name, true)); | 7741 current_block_->scope->LookupVariable(*variable_name, true)); |
| 7911 } | 7742 } |
| 7912 | 7743 |
| 7913 | |
| 7914 void Parser::CaptureFunctionTypeArguments() { | 7744 void Parser::CaptureFunctionTypeArguments() { |
| 7915 ASSERT(InGenericFunctionScope()); | 7745 ASSERT(InGenericFunctionScope()); |
| 7916 ASSERT(FunctionLevel() > 0); | 7746 ASSERT(FunctionLevel() > 0); |
| 7917 if (!FLAG_reify_generic_functions) { | 7747 if (!FLAG_reify_generic_functions) { |
| 7918 return; | 7748 return; |
| 7919 } | 7749 } |
| 7920 const String* variable_name = &Symbols::FunctionTypeArgumentsVar(); | 7750 const String* variable_name = &Symbols::FunctionTypeArgumentsVar(); |
| 7921 current_block_->scope->CaptureVariable( | 7751 current_block_->scope->CaptureVariable( |
| 7922 current_block_->scope->LookupVariable(*variable_name, true)); | 7752 current_block_->scope->LookupVariable(*variable_name, true)); |
| 7923 } | 7753 } |
| 7924 | 7754 |
| 7925 | |
| 7926 void Parser::CaptureAllInstantiators() { | 7755 void Parser::CaptureAllInstantiators() { |
| 7927 if (IsInstantiatorRequired()) { | 7756 if (IsInstantiatorRequired()) { |
| 7928 CaptureInstantiator(); | 7757 CaptureInstantiator(); |
| 7929 } | 7758 } |
| 7930 if (innermost_function().HasGenericParent()) { | 7759 if (innermost_function().HasGenericParent()) { |
| 7931 CaptureFunctionTypeArguments(); | 7760 CaptureFunctionTypeArguments(); |
| 7932 } | 7761 } |
| 7933 } | 7762 } |
| 7934 | 7763 |
| 7935 | |
| 7936 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { | 7764 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { |
| 7937 // A nested function may access 'this', referring to the receiver of the | 7765 // A nested function may access 'this', referring to the receiver of the |
| 7938 // outermost enclosing function. | 7766 // outermost enclosing function. |
| 7939 const bool kTestOnly = false; | 7767 const bool kTestOnly = false; |
| 7940 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7768 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 7941 if (receiver == NULL) { | 7769 if (receiver == NULL) { |
| 7942 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7770 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
| 7943 } | 7771 } |
| 7944 return new (Z) LoadLocalNode(TokenPos(), receiver); | 7772 return new (Z) LoadLocalNode(TokenPos(), receiver); |
| 7945 } | 7773 } |
| 7946 | 7774 |
| 7947 | |
| 7948 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, | 7775 InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos, |
| 7949 AstNode* object, | 7776 AstNode* object, |
| 7950 const String& name) { | 7777 const String& name) { |
| 7951 return new (Z) InstanceGetterNode(token_pos, object, name); | 7778 return new (Z) InstanceGetterNode(token_pos, object, name); |
| 7952 } | 7779 } |
| 7953 | 7780 |
| 7954 | |
| 7955 // Returns ast nodes of the variable initialization. | 7781 // Returns ast nodes of the variable initialization. |
| 7956 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7782 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 7957 bool is_final, | 7783 bool is_final, |
| 7958 bool is_const, | 7784 bool is_const, |
| 7959 SequenceNode** await_preamble) { | 7785 SequenceNode** await_preamble) { |
| 7960 TRACE_PARSER("ParseVariableDeclaration"); | 7786 TRACE_PARSER("ParseVariableDeclaration"); |
| 7961 ASSERT(IsIdentifier()); | 7787 ASSERT(IsIdentifier()); |
| 7962 const TokenPosition ident_pos = TokenPos(); | 7788 const TokenPosition ident_pos = TokenPos(); |
| 7963 const String& ident = *CurrentLiteral(); | 7789 const String& ident = *CurrentLiteral(); |
| 7964 ConsumeToken(); // Variable identifier. | 7790 ConsumeToken(); // Variable identifier. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8015 ASSERT(existing_var->owner() == current_block_->scope); | 7841 ASSERT(existing_var->owner() == current_block_->scope); |
| 8016 ReportError(ident_pos, "identifier '%s' already defined", | 7842 ReportError(ident_pos, "identifier '%s' already defined", |
| 8017 variable->name().ToCString()); | 7843 variable->name().ToCString()); |
| 8018 } | 7844 } |
| 8019 if (is_final || is_const) { | 7845 if (is_final || is_const) { |
| 8020 variable->set_is_final(); | 7846 variable->set_is_final(); |
| 8021 } | 7847 } |
| 8022 return initialization; | 7848 return initialization; |
| 8023 } | 7849 } |
| 8024 | 7850 |
| 8025 | |
| 8026 // Parses ('var' | 'final' [type] | 'const' [type] | type). | 7851 // Parses ('var' | 'final' [type] | 'const' [type] | type). |
| 8027 // The presence of 'final' or 'const' must be detected and remembered | 7852 // The presence of 'final' or 'const' must be detected and remembered |
| 8028 // before the call. If a type is parsed, it may be resolved and finalized | 7853 // before the call. If a type is parsed, it may be resolved and finalized |
| 8029 // according to the given type finalization mode. | 7854 // according to the given type finalization mode. |
| 8030 RawAbstractType* Parser::ParseConstFinalVarOrType( | 7855 RawAbstractType* Parser::ParseConstFinalVarOrType( |
| 8031 ClassFinalizer::FinalizationKind finalization) { | 7856 ClassFinalizer::FinalizationKind finalization) { |
| 8032 TRACE_PARSER("ParseConstFinalVarOrType"); | 7857 TRACE_PARSER("ParseConstFinalVarOrType"); |
| 8033 if (CurrentToken() == Token::kVAR) { | 7858 if (CurrentToken() == Token::kVAR) { |
| 8034 ConsumeToken(); | 7859 ConsumeToken(); |
| 8035 return Type::DynamicType(); | 7860 return Type::DynamicType(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 8056 if ((follower != Token::kLT) && // Parameterized type. | 7881 if ((follower != Token::kLT) && // Parameterized type. |
| 8057 (follower != Token::kPERIOD) && // Qualified class name of type. | 7882 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 8058 !Token::IsIdentifier(follower) && // Variable name following a type. | 7883 !Token::IsIdentifier(follower) && // Variable name following a type. |
| 8059 (follower != Token::kTHIS)) { // Field parameter following a type. | 7884 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 8060 return Type::DynamicType(); | 7885 return Type::DynamicType(); |
| 8061 } | 7886 } |
| 8062 } | 7887 } |
| 8063 return ParseTypeOrFunctionType(false, finalization); | 7888 return ParseTypeOrFunctionType(false, finalization); |
| 8064 } | 7889 } |
| 8065 | 7890 |
| 8066 | |
| 8067 // Returns ast nodes of the variable initialization. Variables without an | 7891 // Returns ast nodes of the variable initialization. Variables without an |
| 8068 // explicit initializer are initialized to null. If several variables are | 7892 // explicit initializer are initialized to null. If several variables are |
| 8069 // declared, the individual initializers are collected in a sequence node. | 7893 // declared, the individual initializers are collected in a sequence node. |
| 8070 AstNode* Parser::ParseVariableDeclarationList() { | 7894 AstNode* Parser::ParseVariableDeclarationList() { |
| 8071 TRACE_PARSER("ParseVariableDeclarationList"); | 7895 TRACE_PARSER("ParseVariableDeclarationList"); |
| 8072 SkipMetadata(); | 7896 SkipMetadata(); |
| 8073 bool is_final = (CurrentToken() == Token::kFINAL); | 7897 bool is_final = (CurrentToken() == Token::kFINAL); |
| 8074 bool is_const = (CurrentToken() == Token::kCONST); | 7898 bool is_const = (CurrentToken() == Token::kCONST); |
| 8075 const AbstractType& type = AbstractType::ZoneHandle( | 7899 const AbstractType& type = AbstractType::ZoneHandle( |
| 8076 Z, | 7900 Z, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8102 ParseVariableDeclaration(type, is_final, is_const, &preamble); | 7926 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
| 8103 if (preamble != NULL) { | 7927 if (preamble != NULL) { |
| 8104 sequence->Add(preamble); | 7928 sequence->Add(preamble); |
| 8105 } | 7929 } |
| 8106 sequence->Add(declaration); | 7930 sequence->Add(declaration); |
| 8107 initializers = sequence; | 7931 initializers = sequence; |
| 8108 } | 7932 } |
| 8109 return initializers; | 7933 return initializers; |
| 8110 } | 7934 } |
| 8111 | 7935 |
| 8112 | |
| 8113 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7936 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 8114 TRACE_PARSER("ParseFunctionStatement"); | 7937 TRACE_PARSER("ParseFunctionStatement"); |
| 8115 AbstractType& result_type = AbstractType::Handle(Z, Type::DynamicType()); | 7938 AbstractType& result_type = AbstractType::Handle(Z, Type::DynamicType()); |
| 8116 const String* function_name = NULL; | 7939 const String* function_name = NULL; |
| 8117 const TokenPosition function_pos = TokenPos(); | 7940 const TokenPosition function_pos = TokenPos(); |
| 8118 TokenPosition function_name_pos = TokenPosition::kNoSource; | 7941 TokenPosition function_name_pos = TokenPosition::kNoSource; |
| 8119 TokenPosition metadata_pos = TokenPosition::kNoSource; | 7942 TokenPosition metadata_pos = TokenPosition::kNoSource; |
| 8120 if (is_literal) { | 7943 if (is_literal) { |
| 8121 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT); | 7944 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT); |
| 8122 function_name = &Symbols::AnonymousClosure(); | 7945 function_name = &Symbols::AnonymousClosure(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8309 // The local scope of the parsed function can be pruned, since contained | 8132 // The local scope of the parsed function can be pruned, since contained |
| 8310 // variables are not relevant for the compilation of the enclosing function. | 8133 // variables are not relevant for the compilation of the enclosing function. |
| 8311 // This pruning is done by omitting to hook the local scope in its parent | 8134 // This pruning is done by omitting to hook the local scope in its parent |
| 8312 // scope in the constructor of LocalScope. | 8135 // scope in the constructor of LocalScope. |
| 8313 AstNode* closure = | 8136 AstNode* closure = |
| 8314 new (Z) ClosureNode(function_pos, function, NULL, | 8137 new (Z) ClosureNode(function_pos, function, NULL, |
| 8315 statements != NULL ? statements->scope() : NULL); | 8138 statements != NULL ? statements->scope() : NULL); |
| 8316 | 8139 |
| 8317 ASSERT(innermost_function_.raw() == function.raw()); | 8140 ASSERT(innermost_function_.raw() == function.raw()); |
| 8318 innermost_function_ = function.parent_function(); | 8141 innermost_function_ = function.parent_function(); |
| 8319 return is_literal ? closure : new (Z) StoreLocalNode( | 8142 return is_literal |
| 8320 function_pos, function_variable, closure); | 8143 ? closure |
| 8144 : new (Z) StoreLocalNode(function_pos, function_variable, closure); |
| 8321 } | 8145 } |
| 8322 | 8146 |
| 8323 | |
| 8324 // Returns true if the current and next tokens can be parsed as type | 8147 // Returns true if the current and next tokens can be parsed as type |
| 8325 // parameters. Current token position is not saved and restored. | 8148 // parameters. Current token position is not saved and restored. |
| 8326 bool Parser::TryParseTypeParameters() { | 8149 bool Parser::TryParseTypeParameters() { |
| 8327 ASSERT(CurrentToken() == Token::kLT); | 8150 ASSERT(CurrentToken() == Token::kLT); |
| 8328 int nesting_level = 0; | 8151 int nesting_level = 0; |
| 8329 do { | 8152 do { |
| 8330 Token::Kind ct = CurrentToken(); | 8153 Token::Kind ct = CurrentToken(); |
| 8331 if (ct == Token::kLT) { | 8154 if (ct == Token::kLT) { |
| 8332 nesting_level++; | 8155 nesting_level++; |
| 8333 } else if (ct == Token::kGT) { | 8156 } else if (ct == Token::kGT) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8346 return false; | 8169 return false; |
| 8347 } | 8170 } |
| 8348 ConsumeToken(); | 8171 ConsumeToken(); |
| 8349 } while (nesting_level > 0); | 8172 } while (nesting_level > 0); |
| 8350 if (nesting_level < 0) { | 8173 if (nesting_level < 0) { |
| 8351 return false; | 8174 return false; |
| 8352 } | 8175 } |
| 8353 return true; | 8176 return true; |
| 8354 } | 8177 } |
| 8355 | 8178 |
| 8356 | |
| 8357 // Returns true if the next tokens can be parsed as type parameters. | 8179 // Returns true if the next tokens can be parsed as type parameters. |
| 8358 bool Parser::IsTypeParameters() { | 8180 bool Parser::IsTypeParameters() { |
| 8359 if (CurrentToken() == Token::kLT) { | 8181 if (CurrentToken() == Token::kLT) { |
| 8360 TokenPosScope param_pos(this); | 8182 TokenPosScope param_pos(this); |
| 8361 if (!TryParseTypeParameters()) { | 8183 if (!TryParseTypeParameters()) { |
| 8362 return false; | 8184 return false; |
| 8363 } | 8185 } |
| 8364 return true; | 8186 return true; |
| 8365 } | 8187 } |
| 8366 return false; | 8188 return false; |
| 8367 } | 8189 } |
| 8368 | 8190 |
| 8369 | |
| 8370 // Returns true if the next tokens are [ typeParameters ] '('. | 8191 // Returns true if the next tokens are [ typeParameters ] '('. |
| 8371 bool Parser::IsParameterPart() { | 8192 bool Parser::IsParameterPart() { |
| 8372 if (CurrentToken() == Token::kLPAREN) { | 8193 if (CurrentToken() == Token::kLPAREN) { |
| 8373 return true; | 8194 return true; |
| 8374 } | 8195 } |
| 8375 if (CurrentToken() == Token::kLT) { | 8196 if (CurrentToken() == Token::kLT) { |
| 8376 TokenPosScope type_arg_pos(this); | 8197 TokenPosScope type_arg_pos(this); |
| 8377 if (!TryParseTypeParameters()) { | 8198 if (!TryParseTypeParameters()) { |
| 8378 return false; | 8199 return false; |
| 8379 } | 8200 } |
| 8380 return CurrentToken() == Token::kLPAREN; | 8201 return CurrentToken() == Token::kLPAREN; |
| 8381 } | 8202 } |
| 8382 return false; | 8203 return false; |
| 8383 } | 8204 } |
| 8384 | 8205 |
| 8385 | |
| 8386 // Returns true if the current and next tokens can be parsed as type | 8206 // Returns true if the current and next tokens can be parsed as type |
| 8387 // arguments. Current token position is not saved and restored. | 8207 // arguments. Current token position is not saved and restored. |
| 8388 bool Parser::TryParseTypeArguments() { | 8208 bool Parser::TryParseTypeArguments() { |
| 8389 ASSERT(CurrentToken() == Token::kLT); | 8209 ASSERT(CurrentToken() == Token::kLT); |
| 8390 int nesting_level = 0; | 8210 int nesting_level = 0; |
| 8391 do { | 8211 do { |
| 8392 Token::Kind ct = CurrentToken(); | 8212 Token::Kind ct = CurrentToken(); |
| 8393 if (ct == Token::kLT) { | 8213 if (ct == Token::kLT) { |
| 8394 nesting_level++; | 8214 nesting_level++; |
| 8395 } else if (ct == Token::kGT) { | 8215 } else if (ct == Token::kGT) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 8413 return false; | 8233 return false; |
| 8414 } | 8234 } |
| 8415 ConsumeToken(); | 8235 ConsumeToken(); |
| 8416 } while (nesting_level > 0); | 8236 } while (nesting_level > 0); |
| 8417 if (nesting_level < 0) { | 8237 if (nesting_level < 0) { |
| 8418 return false; | 8238 return false; |
| 8419 } | 8239 } |
| 8420 return true; | 8240 return true; |
| 8421 } | 8241 } |
| 8422 | 8242 |
| 8423 | |
| 8424 // Returns true if the next tokens are [ typeArguments ] '('. | 8243 // Returns true if the next tokens are [ typeArguments ] '('. |
| 8425 bool Parser::IsArgumentPart() { | 8244 bool Parser::IsArgumentPart() { |
| 8426 if (CurrentToken() == Token::kLPAREN) { | 8245 if (CurrentToken() == Token::kLPAREN) { |
| 8427 return true; | 8246 return true; |
| 8428 } | 8247 } |
| 8429 if (CurrentToken() == Token::kLT) { | 8248 if (CurrentToken() == Token::kLT) { |
| 8430 TokenPosScope type_arg_pos(this); | 8249 TokenPosScope type_arg_pos(this); |
| 8431 if (!TryParseTypeArguments()) { | 8250 if (!TryParseTypeArguments()) { |
| 8432 return false; | 8251 return false; |
| 8433 } | 8252 } |
| 8434 return CurrentToken() == Token::kLPAREN; | 8253 return CurrentToken() == Token::kLPAREN; |
| 8435 } | 8254 } |
| 8436 return false; | 8255 return false; |
| 8437 } | 8256 } |
| 8438 | 8257 |
| 8439 | |
| 8440 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { | 8258 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { |
| 8441 // Assigning null never causes a type error. | 8259 // Assigning null never causes a type error. |
| 8442 if (CurrentToken() == Token::kNULL) { | 8260 if (CurrentToken() == Token::kNULL) { |
| 8443 *value = Instance::null(); | 8261 *value = Instance::null(); |
| 8444 return true; | 8262 return true; |
| 8445 } | 8263 } |
| 8446 // If the type of the const field is guaranteed to be instantiated once | 8264 // If the type of the const field is guaranteed to be instantiated once |
| 8447 // resolved at class finalization time, and if the type of the literal is one | 8265 // resolved at class finalization time, and if the type of the literal is one |
| 8448 // of int, double, String, or bool, then preset the field with the value and | 8266 // of int, double, String, or bool, then preset the field with the value and |
| 8449 // perform the type check (in checked mode only) at finalization time. | 8267 // perform the type check (in checked mode only) at finalization time. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8469 } else if (CurrentToken() == Token::kTRUE) { | 8287 } else if (CurrentToken() == Token::kTRUE) { |
| 8470 *value = Bool::True().raw(); | 8288 *value = Bool::True().raw(); |
| 8471 return true; | 8289 return true; |
| 8472 } else if (CurrentToken() == Token::kFALSE) { | 8290 } else if (CurrentToken() == Token::kFALSE) { |
| 8473 *value = Bool::False().raw(); | 8291 *value = Bool::False().raw(); |
| 8474 return true; | 8292 return true; |
| 8475 } | 8293 } |
| 8476 return false; | 8294 return false; |
| 8477 } | 8295 } |
| 8478 | 8296 |
| 8479 | |
| 8480 // Returns true if the current token is kIDENT or a pseudo-keyword. | 8297 // Returns true if the current token is kIDENT or a pseudo-keyword. |
| 8481 bool Parser::IsIdentifier() { | 8298 bool Parser::IsIdentifier() { |
| 8482 return Token::IsIdentifier(CurrentToken()) && | 8299 return Token::IsIdentifier(CurrentToken()) && |
| 8483 !(await_is_keyword_ && | 8300 !(await_is_keyword_ && |
| 8484 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || | 8301 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || |
| 8485 (CurrentLiteral()->raw() == Symbols::Async().raw()) || | 8302 (CurrentLiteral()->raw() == Symbols::Async().raw()) || |
| 8486 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); | 8303 (CurrentLiteral()->raw() == Symbols::YieldKw().raw()))); |
| 8487 } | 8304 } |
| 8488 | 8305 |
| 8489 | |
| 8490 bool Parser::IsSymbol(const String& symbol) { | 8306 bool Parser::IsSymbol(const String& symbol) { |
| 8491 return (CurrentLiteral()->raw() == symbol.raw()) && | 8307 return (CurrentLiteral()->raw() == symbol.raw()) && |
| 8492 (CurrentToken() == Token::kIDENT); | 8308 (CurrentToken() == Token::kIDENT); |
| 8493 } | 8309 } |
| 8494 | 8310 |
| 8495 | |
| 8496 // Returns true if the current token is 'Function' followed by '<' or '('. | 8311 // Returns true if the current token is 'Function' followed by '<' or '('. |
| 8497 // 'Function' not followed by '<' or '(' denotes the Function class. | 8312 // 'Function' not followed by '<' or '(' denotes the Function class. |
| 8498 bool Parser::IsFunctionTypeSymbol() { | 8313 bool Parser::IsFunctionTypeSymbol() { |
| 8499 return IsSymbol(Symbols::Function()) && | 8314 return IsSymbol(Symbols::Function()) && |
| 8500 ((LookaheadToken(1) == Token::kLPAREN) || | 8315 ((LookaheadToken(1) == Token::kLPAREN) || |
| 8501 (LookaheadToken(1) == Token::kLT)); | 8316 (LookaheadToken(1) == Token::kLT)); |
| 8502 } | 8317 } |
| 8503 | 8318 |
| 8504 | |
| 8505 // Returns true if the next tokens can be parsed as a an optionally | 8319 // Returns true if the next tokens can be parsed as a an optionally |
| 8506 // qualified identifier: [ident '.'] ident. | 8320 // qualified identifier: [ident '.'] ident. |
| 8507 // Current token position is not restored. | 8321 // Current token position is not restored. |
| 8508 bool Parser::TryParseQualIdent() { | 8322 bool Parser::TryParseQualIdent() { |
| 8509 if (CurrentToken() != Token::kIDENT) { | 8323 if (CurrentToken() != Token::kIDENT) { |
| 8510 return false; | 8324 return false; |
| 8511 } | 8325 } |
| 8512 ConsumeToken(); | 8326 ConsumeToken(); |
| 8513 if (CurrentToken() == Token::kPERIOD) { | 8327 if (CurrentToken() == Token::kPERIOD) { |
| 8514 ConsumeToken(); | 8328 ConsumeToken(); |
| 8515 if (CurrentToken() != Token::kIDENT) { | 8329 if (CurrentToken() != Token::kIDENT) { |
| 8516 return false; | 8330 return false; |
| 8517 } | 8331 } |
| 8518 ConsumeToken(); | 8332 ConsumeToken(); |
| 8519 } | 8333 } |
| 8520 return true; | 8334 return true; |
| 8521 } | 8335 } |
| 8522 | 8336 |
| 8523 | |
| 8524 // Returns true if the next tokens can be parsed as a type with optional | 8337 // Returns true if the next tokens can be parsed as a type with optional |
| 8525 // type parameters. Current token position is not restored. | 8338 // type parameters. Current token position is not restored. |
| 8526 // Allow 'void' as type if 'allow_void' is true. | 8339 // Allow 'void' as type if 'allow_void' is true. |
| 8527 // Note that 'void Function()' is always allowed, since it is a function type | 8340 // Note that 'void Function()' is always allowed, since it is a function type |
| 8528 // and not the void type. | 8341 // and not the void type. |
| 8529 bool Parser::TryParseType(bool allow_void) { | 8342 bool Parser::TryParseType(bool allow_void) { |
| 8530 bool found = false; | 8343 bool found = false; |
| 8531 if (CurrentToken() == Token::kVOID) { | 8344 if (CurrentToken() == Token::kVOID) { |
| 8532 ConsumeToken(); | 8345 ConsumeToken(); |
| 8533 if (allow_void) { | 8346 if (allow_void) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8553 if (CurrentToken() == Token::kLPAREN) { | 8366 if (CurrentToken() == Token::kLPAREN) { |
| 8554 SkipToMatchingParenthesis(); | 8367 SkipToMatchingParenthesis(); |
| 8555 } else { | 8368 } else { |
| 8556 return false; | 8369 return false; |
| 8557 } | 8370 } |
| 8558 found = true; | 8371 found = true; |
| 8559 } | 8372 } |
| 8560 return found; | 8373 return found; |
| 8561 } | 8374 } |
| 8562 | 8375 |
| 8563 | |
| 8564 // Look ahead to detect whether the next tokens should be parsed as | 8376 // Look ahead to detect whether the next tokens should be parsed as |
| 8565 // a variable declaration. Ignores optional metadata. | 8377 // a variable declaration. Ignores optional metadata. |
| 8566 // Returns true if we detect the token pattern: | 8378 // Returns true if we detect the token pattern: |
| 8567 // 'var' | 8379 // 'var' |
| 8568 // | 'final' | 8380 // | 'final' |
| 8569 // | const [type] ident (';' | '=' | ',') | 8381 // | const [type] ident (';' | '=' | ',') |
| 8570 // | type ident (';' | '=' | ',') | 8382 // | type ident (';' | '=' | ',') |
| 8571 // Token position remains unchanged. | 8383 // Token position remains unchanged. |
| 8572 bool Parser::IsVariableDeclaration() { | 8384 bool Parser::IsVariableDeclaration() { |
| 8573 if ((CurrentToken() == Token::kVAR) || (CurrentToken() == Token::kFINAL)) { | 8385 if ((CurrentToken() == Token::kVAR) || (CurrentToken() == Token::kFINAL)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8617 if ((CurrentToken() == Token::kSEMICOLON) || | 8429 if ((CurrentToken() == Token::kSEMICOLON) || |
| 8618 (CurrentToken() == Token::kCOMMA) || | 8430 (CurrentToken() == Token::kCOMMA) || |
| 8619 (CurrentToken() == Token::kASSIGN)) { | 8431 (CurrentToken() == Token::kASSIGN)) { |
| 8620 is_var_decl = true; | 8432 is_var_decl = true; |
| 8621 } | 8433 } |
| 8622 } | 8434 } |
| 8623 SetPosition(saved_pos); | 8435 SetPosition(saved_pos); |
| 8624 return is_var_decl; | 8436 return is_var_decl; |
| 8625 } | 8437 } |
| 8626 | 8438 |
| 8627 | |
| 8628 // Look ahead to see if the following tokens are a return type followed | 8439 // Look ahead to see if the following tokens are a return type followed |
| 8629 // by an identifier. | 8440 // by an identifier. |
| 8630 bool Parser::IsFunctionReturnType() { | 8441 bool Parser::IsFunctionReturnType() { |
| 8631 TokenPosScope decl_pos(this); | 8442 TokenPosScope decl_pos(this); |
| 8632 if (TryParseType(true)) { | 8443 if (TryParseType(true)) { |
| 8633 if (IsIdentifier()) { | 8444 if (IsIdentifier()) { |
| 8634 // Return type followed by function name. | 8445 // Return type followed by function name. |
| 8635 return true; | 8446 return true; |
| 8636 } | 8447 } |
| 8637 } | 8448 } |
| 8638 return false; | 8449 return false; |
| 8639 } | 8450 } |
| 8640 | 8451 |
| 8641 | |
| 8642 // Look ahead to detect whether the next tokens should be parsed as | 8452 // Look ahead to detect whether the next tokens should be parsed as |
| 8643 // a function declaration. Token position remains unchanged. | 8453 // a function declaration. Token position remains unchanged. |
| 8644 bool Parser::IsFunctionDeclaration() { | 8454 bool Parser::IsFunctionDeclaration() { |
| 8645 bool is_external = false; | 8455 bool is_external = false; |
| 8646 TokenPosScope decl_pos(this); | 8456 TokenPosScope decl_pos(this); |
| 8647 SkipMetadata(); | 8457 SkipMetadata(); |
| 8648 if ((is_top_level_) && (CurrentToken() == Token::kEXTERNAL)) { | 8458 if ((is_top_level_) && (CurrentToken() == Token::kEXTERNAL)) { |
| 8649 // Skip over 'external' for top-level function declarations. | 8459 // Skip over 'external' for top-level function declarations. |
| 8650 is_external = true; | 8460 is_external = true; |
| 8651 ConsumeToken(); | 8461 ConsumeToken(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 8675 // Check parameter list and the following token. | 8485 // Check parameter list and the following token. |
| 8676 SkipToMatchingParenthesis(); | 8486 SkipToMatchingParenthesis(); |
| 8677 if ((CurrentToken() == Token::kLBRACE) || (CurrentToken() == Token::kARROW) || | 8487 if ((CurrentToken() == Token::kLBRACE) || (CurrentToken() == Token::kARROW) || |
| 8678 (is_top_level_ && IsSymbol(Symbols::Native())) || is_external || | 8488 (is_top_level_ && IsSymbol(Symbols::Native())) || is_external || |
| 8679 IsSymbol(Symbols::Async()) || IsSymbol(Symbols::Sync())) { | 8489 IsSymbol(Symbols::Async()) || IsSymbol(Symbols::Sync())) { |
| 8680 return true; | 8490 return true; |
| 8681 } | 8491 } |
| 8682 return false; | 8492 return false; |
| 8683 } | 8493 } |
| 8684 | 8494 |
| 8685 | |
| 8686 bool Parser::IsTopLevelAccessor() { | 8495 bool Parser::IsTopLevelAccessor() { |
| 8687 const TokenPosScope saved_pos(this); | 8496 const TokenPosScope saved_pos(this); |
| 8688 if (CurrentToken() == Token::kEXTERNAL) { | 8497 if (CurrentToken() == Token::kEXTERNAL) { |
| 8689 ConsumeToken(); | 8498 ConsumeToken(); |
| 8690 } | 8499 } |
| 8691 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 8500 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 8692 return true; | 8501 return true; |
| 8693 } | 8502 } |
| 8694 if (TryParseType(true)) { | 8503 if (TryParseType(true)) { |
| 8695 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 8504 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 8696 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 8505 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 8697 return true; | 8506 return true; |
| 8698 } | 8507 } |
| 8699 } | 8508 } |
| 8700 } | 8509 } |
| 8701 return false; | 8510 return false; |
| 8702 } | 8511 } |
| 8703 | 8512 |
| 8704 | |
| 8705 bool Parser::IsFunctionLiteral() { | 8513 bool Parser::IsFunctionLiteral() { |
| 8706 if (!allow_function_literals_) { | 8514 if (!allow_function_literals_) { |
| 8707 return false; | 8515 return false; |
| 8708 } | 8516 } |
| 8709 if ((CurrentToken() == Token::kLPAREN) || (CurrentToken() == Token::kLT)) { | 8517 if ((CurrentToken() == Token::kLPAREN) || (CurrentToken() == Token::kLT)) { |
| 8710 TokenPosScope saved_pos(this); | 8518 TokenPosScope saved_pos(this); |
| 8711 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { | 8519 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { |
| 8712 return false; | 8520 return false; |
| 8713 } | 8521 } |
| 8714 if (CurrentToken() != Token::kLPAREN) { | 8522 if (CurrentToken() != Token::kLPAREN) { |
| 8715 return false; | 8523 return false; |
| 8716 } | 8524 } |
| 8717 SkipToMatchingParenthesis(); | 8525 SkipToMatchingParenthesis(); |
| 8718 ParseFunctionModifier(); | 8526 ParseFunctionModifier(); |
| 8719 if ((CurrentToken() == Token::kLBRACE) || | 8527 if ((CurrentToken() == Token::kLBRACE) || |
| 8720 (CurrentToken() == Token::kARROW)) { | 8528 (CurrentToken() == Token::kARROW)) { |
| 8721 return true; | 8529 return true; |
| 8722 } | 8530 } |
| 8723 } | 8531 } |
| 8724 return false; | 8532 return false; |
| 8725 } | 8533 } |
| 8726 | 8534 |
| 8727 | |
| 8728 // Current token position is the token after the opening ( of the for | 8535 // Current token position is the token after the opening ( of the for |
| 8729 // statement. Returns true if we recognize a for ( .. in expr) | 8536 // statement. Returns true if we recognize a for ( .. in expr) |
| 8730 // statement. | 8537 // statement. |
| 8731 bool Parser::IsForInStatement() { | 8538 bool Parser::IsForInStatement() { |
| 8732 const TokenPosScope saved_pos(this); | 8539 const TokenPosScope saved_pos(this); |
| 8733 // Allow const modifier as well when recognizing a for-in statement | 8540 // Allow const modifier as well when recognizing a for-in statement |
| 8734 // pattern. We will get an error later if the loop variable is | 8541 // pattern. We will get an error later if the loop variable is |
| 8735 // declared with const. | 8542 // declared with const. |
| 8736 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL || | 8543 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL || |
| 8737 CurrentToken() == Token::kCONST) { | 8544 CurrentToken() == Token::kCONST) { |
| 8738 ConsumeToken(); | 8545 ConsumeToken(); |
| 8739 } | 8546 } |
| 8740 if (IsIdentifier()) { | 8547 if (IsIdentifier()) { |
| 8741 if (LookaheadToken(1) == Token::kIN) { | 8548 if (LookaheadToken(1) == Token::kIN) { |
| 8742 return true; | 8549 return true; |
| 8743 } else if (TryParseType(false)) { | 8550 } else if (TryParseType(false)) { |
| 8744 if (IsIdentifier()) { | 8551 if (IsIdentifier()) { |
| 8745 ConsumeToken(); | 8552 ConsumeToken(); |
| 8746 } | 8553 } |
| 8747 return CurrentToken() == Token::kIN; | 8554 return CurrentToken() == Token::kIN; |
| 8748 } | 8555 } |
| 8749 } | 8556 } |
| 8750 return false; | 8557 return false; |
| 8751 } | 8558 } |
| 8752 | 8559 |
| 8753 | |
| 8754 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); | 8560 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); |
| 8755 | 8561 |
| 8756 static bool IsAbruptCompleting(AstNode* statement) { | 8562 static bool IsAbruptCompleting(AstNode* statement) { |
| 8757 return statement->IsReturnNode() || statement->IsJumpNode() || | 8563 return statement->IsReturnNode() || statement->IsJumpNode() || |
| 8758 statement->IsThrowNode() || | 8564 statement->IsThrowNode() || |
| 8759 (statement->IsSequenceNode() && | 8565 (statement->IsSequenceNode() && |
| 8760 ContainsAbruptCompletingStatement(statement->AsSequenceNode())); | 8566 ContainsAbruptCompletingStatement(statement->AsSequenceNode())); |
| 8761 } | 8567 } |
| 8762 | 8568 |
| 8763 | |
| 8764 static bool ContainsAbruptCompletingStatement(SequenceNode* seq) { | 8569 static bool ContainsAbruptCompletingStatement(SequenceNode* seq) { |
| 8765 for (int i = 0; i < seq->length(); i++) { | 8570 for (int i = 0; i < seq->length(); i++) { |
| 8766 if (IsAbruptCompleting(seq->NodeAt(i))) { | 8571 if (IsAbruptCompleting(seq->NodeAt(i))) { |
| 8767 return true; | 8572 return true; |
| 8768 } | 8573 } |
| 8769 } | 8574 } |
| 8770 return false; | 8575 return false; |
| 8771 } | 8576 } |
| 8772 | 8577 |
| 8773 | |
| 8774 void Parser::ParseStatementSequence() { | 8578 void Parser::ParseStatementSequence() { |
| 8775 TRACE_PARSER("ParseStatementSequence"); | 8579 TRACE_PARSER("ParseStatementSequence"); |
| 8776 const bool dead_code_allowed = true; | 8580 const bool dead_code_allowed = true; |
| 8777 bool abrupt_completing_seen = false; | 8581 bool abrupt_completing_seen = false; |
| 8778 RecursionChecker rc(this); | 8582 RecursionChecker rc(this); |
| 8779 while (CurrentToken() != Token::kRBRACE) { | 8583 while (CurrentToken() != Token::kRBRACE) { |
| 8780 const TokenPosition statement_pos = TokenPos(); | 8584 const TokenPosition statement_pos = TokenPos(); |
| 8781 AstNode* statement = ParseStatement(); | 8585 AstNode* statement = ParseStatement(); |
| 8782 // Do not add statements with no effect (e.g., LoadLocalNode). | 8586 // Do not add statements with no effect (e.g., LoadLocalNode). |
| 8783 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 8587 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
| 8784 // Skip load local. | 8588 // Skip load local. |
| 8785 continue; | 8589 continue; |
| 8786 } | 8590 } |
| 8787 if (statement != NULL) { | 8591 if (statement != NULL) { |
| 8788 if (!dead_code_allowed && abrupt_completing_seen) { | 8592 if (!dead_code_allowed && abrupt_completing_seen) { |
| 8789 ReportError(statement_pos, | 8593 ReportError(statement_pos, |
| 8790 "dead code after abrupt completing statement"); | 8594 "dead code after abrupt completing statement"); |
| 8791 } | 8595 } |
| 8792 current_block_->statements->Add(statement); | 8596 current_block_->statements->Add(statement); |
| 8793 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8597 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 8794 } | 8598 } |
| 8795 } | 8599 } |
| 8796 } | 8600 } |
| 8797 | 8601 |
| 8798 | |
| 8799 // Parse nested statement of if, while, for, etc. We automatically generate | 8602 // Parse nested statement of if, while, for, etc. We automatically generate |
| 8800 // a sequence of one statement if there are no curly braces. | 8603 // a sequence of one statement if there are no curly braces. |
| 8801 // The argument 'parsing_loop_body' indicates the parsing of a loop statement. | 8604 // The argument 'parsing_loop_body' indicates the parsing of a loop statement. |
| 8802 SequenceNode* Parser::ParseNestedStatement(bool parsing_loop_body, | 8605 SequenceNode* Parser::ParseNestedStatement(bool parsing_loop_body, |
| 8803 SourceLabel* label) { | 8606 SourceLabel* label) { |
| 8804 TRACE_PARSER("ParseNestedStatement"); | 8607 TRACE_PARSER("ParseNestedStatement"); |
| 8805 if (parsing_loop_body) { | 8608 if (parsing_loop_body) { |
| 8806 OpenLoopBlock(); | 8609 OpenLoopBlock(); |
| 8807 } else { | 8610 } else { |
| 8808 OpenBlock(); | 8611 OpenBlock(); |
| 8809 } | 8612 } |
| 8810 if (label != NULL) { | 8613 if (label != NULL) { |
| 8811 current_block_->scope->AddLabel(label); | 8614 current_block_->scope->AddLabel(label); |
| 8812 } | 8615 } |
| 8813 if (CurrentToken() == Token::kLBRACE) { | 8616 if (CurrentToken() == Token::kLBRACE) { |
| 8814 ConsumeToken(); | 8617 ConsumeToken(); |
| 8815 ParseStatementSequence(); | 8618 ParseStatementSequence(); |
| 8816 ExpectToken(Token::kRBRACE); | 8619 ExpectToken(Token::kRBRACE); |
| 8817 } else { | 8620 } else { |
| 8818 RecursionChecker rc(this); | 8621 RecursionChecker rc(this); |
| 8819 AstNode* statement = ParseStatement(); | 8622 AstNode* statement = ParseStatement(); |
| 8820 if (statement != NULL) { | 8623 if (statement != NULL) { |
| 8821 current_block_->statements->Add(statement); | 8624 current_block_->statements->Add(statement); |
| 8822 } | 8625 } |
| 8823 } | 8626 } |
| 8824 SequenceNode* sequence = CloseBlock(); | 8627 SequenceNode* sequence = CloseBlock(); |
| 8825 return sequence; | 8628 return sequence; |
| 8826 } | 8629 } |
| 8827 | 8630 |
| 8828 | |
| 8829 AstNode* Parser::ParseIfStatement(String* label_name) { | 8631 AstNode* Parser::ParseIfStatement(String* label_name) { |
| 8830 TRACE_PARSER("ParseIfStatement"); | 8632 TRACE_PARSER("ParseIfStatement"); |
| 8831 ASSERT(CurrentToken() == Token::kIF); | 8633 ASSERT(CurrentToken() == Token::kIF); |
| 8832 const TokenPosition if_pos = TokenPos(); | 8634 const TokenPosition if_pos = TokenPos(); |
| 8833 SourceLabel* label = NULL; | 8635 SourceLabel* label = NULL; |
| 8834 if (label_name != NULL) { | 8636 if (label_name != NULL) { |
| 8835 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 8637 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
| 8836 OpenBlock(); | 8638 OpenBlock(); |
| 8837 current_block_->scope->AddLabel(label); | 8639 current_block_->scope->AddLabel(label); |
| 8838 } | 8640 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8851 new (Z) IfNode(if_pos, cond_expr, true_branch, false_branch); | 8653 new (Z) IfNode(if_pos, cond_expr, true_branch, false_branch); |
| 8852 if (label != NULL) { | 8654 if (label != NULL) { |
| 8853 current_block_->statements->Add(if_node); | 8655 current_block_->statements->Add(if_node); |
| 8854 SequenceNode* sequence = CloseBlock(); | 8656 SequenceNode* sequence = CloseBlock(); |
| 8855 sequence->set_label(label); | 8657 sequence->set_label(label); |
| 8856 if_node = sequence; | 8658 if_node = sequence; |
| 8857 } | 8659 } |
| 8858 return if_node; | 8660 return if_node; |
| 8859 } | 8661 } |
| 8860 | 8662 |
| 8861 | |
| 8862 // Return true if the type class of the given value implements the | 8663 // Return true if the type class of the given value implements the |
| 8863 // == operator. | 8664 // == operator. |
| 8864 static bool ImplementsEqualOperator(Zone* zone, const Instance& value) { | 8665 static bool ImplementsEqualOperator(Zone* zone, const Instance& value) { |
| 8865 Class& cls = Class::Handle(value.clazz()); | 8666 Class& cls = Class::Handle(value.clazz()); |
| 8866 const Function& equal_op = Function::Handle( | 8667 const Function& equal_op = Function::Handle( |
| 8867 zone, | 8668 zone, |
| 8868 Resolver::ResolveDynamicAnyArgs(zone, cls, Symbols::EqualOperator())); | 8669 Resolver::ResolveDynamicAnyArgs(zone, cls, Symbols::EqualOperator())); |
| 8869 ASSERT(!equal_op.IsNull()); | 8670 ASSERT(!equal_op.IsNull()); |
| 8870 cls = equal_op.Owner(); | 8671 cls = equal_op.Owner(); |
| 8871 return !cls.IsObjectClass(); | 8672 return !cls.IsObjectClass(); |
| 8872 } | 8673 } |
| 8873 | 8674 |
| 8874 | |
| 8875 // Check that all case expressions are of the same type, either int, String, | 8675 // Check that all case expressions are of the same type, either int, String, |
| 8876 // or any other class that does not override the == operator. | 8676 // or any other class that does not override the == operator. |
| 8877 // The expressions are compile-time constants and are thus in the form | 8677 // The expressions are compile-time constants and are thus in the form |
| 8878 // of a LiteralNode. | 8678 // of a LiteralNode. |
| 8879 RawClass* Parser::CheckCaseExpressions( | 8679 RawClass* Parser::CheckCaseExpressions( |
| 8880 const GrowableArray<LiteralNode*>& values) { | 8680 const GrowableArray<LiteralNode*>& values) { |
| 8881 const intptr_t num_expressions = values.length(); | 8681 const intptr_t num_expressions = values.length(); |
| 8882 if (num_expressions == 0) { | 8682 if (num_expressions == 0) { |
| 8883 return Object::dynamic_class(); | 8683 return Object::dynamic_class(); |
| 8884 } | 8684 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8920 } | 8720 } |
| 8921 } | 8721 } |
| 8922 if (first_value.IsInteger()) { | 8722 if (first_value.IsInteger()) { |
| 8923 return Type::Handle(Z, Type::IntType()).type_class(); | 8723 return Type::Handle(Z, Type::IntType()).type_class(); |
| 8924 } else if (first_value.IsString()) { | 8724 } else if (first_value.IsString()) { |
| 8925 return Type::Handle(Z, Type::StringType()).type_class(); | 8725 return Type::Handle(Z, Type::StringType()).type_class(); |
| 8926 } | 8726 } |
| 8927 return first_value.clazz(); | 8727 return first_value.clazz(); |
| 8928 } | 8728 } |
| 8929 | 8729 |
| 8930 | |
| 8931 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 8730 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 8932 GrowableArray<LiteralNode*>* case_expr_values, | 8731 GrowableArray<LiteralNode*>* case_expr_values, |
| 8933 SourceLabel* case_label) { | 8732 SourceLabel* case_label) { |
| 8934 TRACE_PARSER("ParseCaseClause"); | 8733 TRACE_PARSER("ParseCaseClause"); |
| 8935 bool default_seen = false; | 8734 bool default_seen = false; |
| 8936 const TokenPosition case_pos = TokenPos(); | 8735 const TokenPosition case_pos = TokenPos(); |
| 8937 // The case expressions node sequence does not own the enclosing scope. | 8736 // The case expressions node sequence does not own the enclosing scope. |
| 8938 SequenceNode* case_expressions = new (Z) SequenceNode(case_pos, NULL); | 8737 SequenceNode* case_expressions = new (Z) SequenceNode(case_pos, NULL); |
| 8939 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 8738 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 8940 if (CurrentToken() == Token::kCASE) { | 8739 if (CurrentToken() == Token::kCASE) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8998 if (statement != NULL) { | 8797 if (statement != NULL) { |
| 8999 current_block_->statements->Add(statement); | 8798 current_block_->statements->Add(statement); |
| 9000 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8799 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 9001 } | 8800 } |
| 9002 } | 8801 } |
| 9003 SequenceNode* statements = CloseBlock(); | 8802 SequenceNode* statements = CloseBlock(); |
| 9004 return new (Z) CaseNode(case_pos, case_label, case_expressions, default_seen, | 8803 return new (Z) CaseNode(case_pos, case_label, case_expressions, default_seen, |
| 9005 switch_expr_value, statements); | 8804 switch_expr_value, statements); |
| 9006 } | 8805 } |
| 9007 | 8806 |
| 9008 | |
| 9009 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 8807 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 9010 TRACE_PARSER("ParseSwitchStatement"); | 8808 TRACE_PARSER("ParseSwitchStatement"); |
| 9011 ASSERT(CurrentToken() == Token::kSWITCH); | 8809 ASSERT(CurrentToken() == Token::kSWITCH); |
| 9012 const TokenPosition switch_pos = TokenPos(); | 8810 const TokenPosition switch_pos = TokenPos(); |
| 9013 SourceLabel* label = | 8811 SourceLabel* label = |
| 9014 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 8812 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 9015 ConsumeToken(); | 8813 ConsumeToken(); |
| 9016 ExpectToken(Token::kLPAREN); | 8814 ExpectToken(Token::kLPAREN); |
| 9017 const TokenPosition expr_pos = TokenPos(); | 8815 const TokenPosition expr_pos = TokenPos(); |
| 9018 AstNode* switch_expr = | 8816 AstNode* switch_expr = |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9097 if (unresolved_label != NULL) { | 8895 if (unresolved_label != NULL) { |
| 9098 ReportError("unresolved reference to label '%s'", | 8896 ReportError("unresolved reference to label '%s'", |
| 9099 unresolved_label->name().ToCString()); | 8897 unresolved_label->name().ToCString()); |
| 9100 } | 8898 } |
| 9101 | 8899 |
| 9102 SequenceNode* switch_body = CloseBlock(); | 8900 SequenceNode* switch_body = CloseBlock(); |
| 9103 ExpectToken(Token::kRBRACE); | 8901 ExpectToken(Token::kRBRACE); |
| 9104 return new (Z) SwitchNode(switch_pos, label, switch_body); | 8902 return new (Z) SwitchNode(switch_pos, label, switch_body); |
| 9105 } | 8903 } |
| 9106 | 8904 |
| 9107 | |
| 9108 AstNode* Parser::ParseWhileStatement(String* label_name) { | 8905 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 9109 TRACE_PARSER("ParseWhileStatement"); | 8906 TRACE_PARSER("ParseWhileStatement"); |
| 9110 const TokenPosition while_pos = TokenPos(); | 8907 const TokenPosition while_pos = TokenPos(); |
| 9111 SourceLabel* label = | 8908 SourceLabel* label = |
| 9112 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 8909 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 9113 ConsumeToken(); | 8910 ConsumeToken(); |
| 9114 ExpectToken(Token::kLPAREN); | 8911 ExpectToken(Token::kLPAREN); |
| 9115 SequenceNode* await_preamble = NULL; | 8912 SequenceNode* await_preamble = NULL; |
| 9116 AstNode* cond_expr = | 8913 AstNode* cond_expr = |
| 9117 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8914 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
| 9118 ExpectToken(Token::kRPAREN); | 8915 ExpectToken(Token::kRPAREN); |
| 9119 const bool parsing_loop_body = true; | 8916 const bool parsing_loop_body = true; |
| 9120 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 8917 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 9121 WhileNode* while_node = new (Z) | 8918 WhileNode* while_node = new (Z) |
| 9122 WhileNode(while_pos, label, cond_expr, await_preamble, while_body); | 8919 WhileNode(while_pos, label, cond_expr, await_preamble, while_body); |
| 9123 return while_node; | 8920 return while_node; |
| 9124 } | 8921 } |
| 9125 | 8922 |
| 9126 | |
| 9127 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 8923 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 9128 TRACE_PARSER("ParseDoWhileStatement"); | 8924 TRACE_PARSER("ParseDoWhileStatement"); |
| 9129 const TokenPosition do_pos = TokenPos(); | 8925 const TokenPosition do_pos = TokenPos(); |
| 9130 SourceLabel* label = | 8926 SourceLabel* label = |
| 9131 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 8927 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 9132 ConsumeToken(); | 8928 ConsumeToken(); |
| 9133 const bool parsing_loop_body = true; | 8929 const bool parsing_loop_body = true; |
| 9134 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 8930 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 9135 ExpectToken(Token::kWHILE); | 8931 ExpectToken(Token::kWHILE); |
| 9136 ExpectToken(Token::kLPAREN); | 8932 ExpectToken(Token::kLPAREN); |
| 9137 SequenceNode* await_preamble = NULL; | 8933 SequenceNode* await_preamble = NULL; |
| 9138 TokenPosition expr_pos = TokenPos(); | 8934 TokenPosition expr_pos = TokenPos(); |
| 9139 AstNode* cond_expr = | 8935 AstNode* cond_expr = |
| 9140 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8936 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
| 9141 if (await_preamble != NULL) { | 8937 if (await_preamble != NULL) { |
| 9142 // Prepend the preamble to the condition. | 8938 // Prepend the preamble to the condition. |
| 9143 LetNode* await_cond = new (Z) LetNode(expr_pos); | 8939 LetNode* await_cond = new (Z) LetNode(expr_pos); |
| 9144 await_cond->AddNode(await_preamble); | 8940 await_cond->AddNode(await_preamble); |
| 9145 await_cond->AddNode(cond_expr); | 8941 await_cond->AddNode(cond_expr); |
| 9146 cond_expr = await_cond; | 8942 cond_expr = await_cond; |
| 9147 } | 8943 } |
| 9148 ExpectToken(Token::kRPAREN); | 8944 ExpectToken(Token::kRPAREN); |
| 9149 ExpectSemicolon(); | 8945 ExpectSemicolon(); |
| 9150 return new (Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 8946 return new (Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 9151 } | 8947 } |
| 9152 | 8948 |
| 9153 | |
| 9154 static LocalVariable* LookupSavedTryContextVar(LocalScope* scope) { | 8949 static LocalVariable* LookupSavedTryContextVar(LocalScope* scope) { |
| 9155 LocalVariable* var = | 8950 LocalVariable* var = |
| 9156 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 8951 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 9157 ASSERT((var != NULL) && !var->is_captured()); | 8952 ASSERT((var != NULL) && !var->is_captured()); |
| 9158 return var; | 8953 return var; |
| 9159 } | 8954 } |
| 9160 | 8955 |
| 9161 | |
| 9162 static LocalVariable* LookupAsyncSavedTryContextVar(Thread* thread, | 8956 static LocalVariable* LookupAsyncSavedTryContextVar(Thread* thread, |
| 9163 LocalScope* scope, | 8957 LocalScope* scope, |
| 9164 uint16_t try_index) { | 8958 uint16_t try_index) { |
| 9165 Zone* zone = thread->zone(); | 8959 Zone* zone = thread->zone(); |
| 9166 const String& async_saved_try_ctx_name = String::ZoneHandle( | 8960 const String& async_saved_try_ctx_name = String::ZoneHandle( |
| 9167 zone, Symbols::NewFormatted( | 8961 zone, Symbols::NewFormatted( |
| 9168 thread, "%s%d", | 8962 thread, "%s%d", |
| 9169 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), try_index)); | 8963 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), try_index)); |
| 9170 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); | 8964 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); |
| 9171 ASSERT(var != NULL); | 8965 ASSERT(var != NULL); |
| 9172 return var; | 8966 return var; |
| 9173 } | 8967 } |
| 9174 | 8968 |
| 9175 | |
| 9176 // If the await or yield being parsed is in a try block, the continuation code | 8969 // If the await or yield being parsed is in a try block, the continuation code |
| 9177 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, | 8970 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, |
| 9178 // and the stack-based variable :saved_try_ctx_var of the outer try block. | 8971 // and the stack-based variable :saved_try_ctx_var of the outer try block. |
| 9179 // The inner :saved_try_ctx_var is used by a finally clause handling an | 8972 // The inner :saved_try_ctx_var is used by a finally clause handling an |
| 9180 // exception thrown by the continuation code in a try block or catch block. | 8973 // exception thrown by the continuation code in a try block or catch block. |
| 9181 // If no finally clause exists, the catch or finally clause of the outer try | 8974 // If no finally clause exists, the catch or finally clause of the outer try |
| 9182 // block, if any, uses the outer :saved_try_ctx_var to handle the exception. | 8975 // block, if any, uses the outer :saved_try_ctx_var to handle the exception. |
| 9183 // | 8976 // |
| 9184 // * Try blocks and catch blocks: | 8977 // * Try blocks and catch blocks: |
| 9185 // Set the context variable for this try block and for the outer try block. | 8978 // Set the context variable for this try block and for the outer try block. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9221 } | 9014 } |
| 9222 // An async or async* has an implicitly created try-catch around the | 9015 // An async or async* has an implicitly created try-catch around the |
| 9223 // function body, so the await or yield inside the async closure should always | 9016 // function body, so the await or yield inside the async closure should always |
| 9224 // be created with a try scope. | 9017 // be created with a try scope. |
| 9225 ASSERT((*saved_try_ctx != NULL) || innermost_function().IsAsyncFunction() || | 9018 ASSERT((*saved_try_ctx != NULL) || innermost_function().IsAsyncFunction() || |
| 9226 innermost_function().IsAsyncGenerator() || | 9019 innermost_function().IsAsyncGenerator() || |
| 9227 innermost_function().IsSyncGenClosure() || | 9020 innermost_function().IsSyncGenClosure() || |
| 9228 innermost_function().IsSyncGenerator()); | 9021 innermost_function().IsSyncGenerator()); |
| 9229 } | 9022 } |
| 9230 | 9023 |
| 9231 | |
| 9232 // Build an AST node for static call to Dart function print(str). | 9024 // Build an AST node for static call to Dart function print(str). |
| 9233 // Used during debugging to insert print in generated dart code. | 9025 // Used during debugging to insert print in generated dart code. |
| 9234 AstNode* Parser::DartPrint(const char* str) { | 9026 AstNode* Parser::DartPrint(const char* str) { |
| 9235 const Library& lib = Library::Handle(Library::CoreLibrary()); | 9027 const Library& lib = Library::Handle(Library::CoreLibrary()); |
| 9236 const Function& print_fn = | 9028 const Function& print_fn = |
| 9237 Function::ZoneHandle(Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 9029 Function::ZoneHandle(Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
| 9238 ASSERT(!print_fn.IsNull()); | 9030 ASSERT(!print_fn.IsNull()); |
| 9239 ArgumentListNode* one_arg = | 9031 ArgumentListNode* one_arg = |
| 9240 new (Z) ArgumentListNode(TokenPosition::kNoSource); | 9032 new (Z) ArgumentListNode(TokenPosition::kNoSource); |
| 9241 String& msg = String::ZoneHandle(Symbols::NewFormatted(T, "%s", str)); | 9033 String& msg = String::ZoneHandle(Symbols::NewFormatted(T, "%s", str)); |
| 9242 one_arg->Add(new (Z) LiteralNode(TokenPosition::kNoSource, msg)); | 9034 one_arg->Add(new (Z) LiteralNode(TokenPosition::kNoSource, msg)); |
| 9243 AstNode* print_call = | 9035 AstNode* print_call = |
| 9244 new (Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); | 9036 new (Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg); |
| 9245 return print_call; | 9037 return print_call; |
| 9246 } | 9038 } |
| 9247 | 9039 |
| 9248 | |
| 9249 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 9040 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
| 9250 TRACE_PARSER("ParseAwaitForStatement"); | 9041 TRACE_PARSER("ParseAwaitForStatement"); |
| 9251 ASSERT(IsAwaitKeyword()); | 9042 ASSERT(IsAwaitKeyword()); |
| 9252 const TokenPosition await_for_pos = TokenPos(); | 9043 const TokenPosition await_for_pos = TokenPos(); |
| 9253 ConsumeToken(); // await. | 9044 ConsumeToken(); // await. |
| 9254 ASSERT(CurrentToken() == Token::kFOR); | 9045 ASSERT(CurrentToken() == Token::kFOR); |
| 9255 ConsumeToken(); // for. | 9046 ConsumeToken(); // for. |
| 9256 ExpectToken(Token::kLPAREN); | 9047 ExpectToken(Token::kLPAREN); |
| 9257 | 9048 |
| 9258 if (!innermost_function().IsAsyncFunction() && | 9049 if (!innermost_function().IsAsyncFunction() && |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9556 AstNode* try_catch_node = | 9347 AstNode* try_catch_node = |
| 9557 new (Z) TryCatchNode(await_for_pos, try_block, context_var, catch_clause, | 9348 new (Z) TryCatchNode(await_for_pos, try_block, context_var, catch_clause, |
| 9558 finally_clause, try_index, finally_clause); | 9349 finally_clause, try_index, finally_clause); |
| 9559 | 9350 |
| 9560 ASSERT(current_block_ == await_for_block); | 9351 ASSERT(current_block_ == await_for_block); |
| 9561 await_for_block->statements->Add(try_catch_node); | 9352 await_for_block->statements->Add(try_catch_node); |
| 9562 | 9353 |
| 9563 return CloseBlock(); // Implicit block around while loop. | 9354 return CloseBlock(); // Implicit block around while loop. |
| 9564 } | 9355 } |
| 9565 | 9356 |
| 9566 | |
| 9567 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, | 9357 AstNode* Parser::ParseForInStatement(TokenPosition forin_pos, |
| 9568 SourceLabel* label) { | 9358 SourceLabel* label) { |
| 9569 TRACE_PARSER("ParseForInStatement"); | 9359 TRACE_PARSER("ParseForInStatement"); |
| 9570 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 9360 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
| 9571 if (CurrentToken() == Token::kCONST) { | 9361 if (CurrentToken() == Token::kCONST) { |
| 9572 ReportError("Loop variable cannot be 'const'"); | 9362 ReportError("Loop variable cannot be 'const'"); |
| 9573 } | 9363 } |
| 9574 const String* loop_var_name = NULL; | 9364 const String* loop_var_name = NULL; |
| 9575 TokenPosition loop_var_pos = TokenPosition::kNoSource; | 9365 TokenPosition loop_var_pos = TokenPosition::kNoSource; |
| 9576 bool new_loop_var = false; | 9366 bool new_loop_var = false; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9677 | 9467 |
| 9678 SequenceNode* for_loop_statement = CloseBlock(); | 9468 SequenceNode* for_loop_statement = CloseBlock(); |
| 9679 | 9469 |
| 9680 AstNode* while_statement = new (Z) | 9470 AstNode* while_statement = new (Z) |
| 9681 WhileNode(forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 9471 WhileNode(forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
| 9682 current_block_->statements->Add(while_statement); | 9472 current_block_->statements->Add(while_statement); |
| 9683 | 9473 |
| 9684 return CloseBlock(); // Implicit block around while loop. | 9474 return CloseBlock(); // Implicit block around while loop. |
| 9685 } | 9475 } |
| 9686 | 9476 |
| 9687 | |
| 9688 AstNode* Parser::ParseForStatement(String* label_name) { | 9477 AstNode* Parser::ParseForStatement(String* label_name) { |
| 9689 TRACE_PARSER("ParseForStatement"); | 9478 TRACE_PARSER("ParseForStatement"); |
| 9690 const TokenPosition for_pos = TokenPos(); | 9479 const TokenPosition for_pos = TokenPos(); |
| 9691 ConsumeToken(); | 9480 ConsumeToken(); |
| 9692 ExpectToken(Token::kLPAREN); | 9481 ExpectToken(Token::kLPAREN); |
| 9693 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 9482 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
| 9694 if (IsForInStatement()) { | 9483 if (IsForInStatement()) { |
| 9695 return ParseForInStatement(for_pos, label); | 9484 return ParseForInStatement(for_pos, label); |
| 9696 } | 9485 } |
| 9697 // Open a block that contains the loop variable. Make it a loop block so | 9486 // Open a block that contains the loop variable. Make it a loop block so |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9741 } | 9530 } |
| 9742 } | 9531 } |
| 9743 AstNode* for_node = new (Z) | 9532 AstNode* for_node = new (Z) |
| 9744 ForNode(for_pos, label, NodeAsSequenceNode(init_pos, initializer, NULL), | 9533 ForNode(for_pos, label, NodeAsSequenceNode(init_pos, initializer, NULL), |
| 9745 condition, condition_preamble, | 9534 condition, condition_preamble, |
| 9746 NodeAsSequenceNode(incr_pos, increment, NULL), body); | 9535 NodeAsSequenceNode(incr_pos, increment, NULL), body); |
| 9747 current_block_->statements->Add(for_node); | 9536 current_block_->statements->Add(for_node); |
| 9748 return CloseBlock(); | 9537 return CloseBlock(); |
| 9749 } | 9538 } |
| 9750 | 9539 |
| 9751 | |
| 9752 // Calling VM-internal helpers, uses implementation core library. | 9540 // Calling VM-internal helpers, uses implementation core library. |
| 9753 AstNode* Parser::MakeStaticCall(const String& cls_name, | 9541 AstNode* Parser::MakeStaticCall(const String& cls_name, |
| 9754 const String& func_name, | 9542 const String& func_name, |
| 9755 ArgumentListNode* arguments) { | 9543 ArgumentListNode* arguments) { |
| 9756 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); | 9544 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); |
| 9757 ASSERT(!cls.IsNull()); | 9545 ASSERT(!cls.IsNull()); |
| 9758 const intptr_t kTypeArgsLen = 0; // Not passing type args to generic func. | 9546 const intptr_t kTypeArgsLen = 0; // Not passing type args to generic func. |
| 9759 const Function& func = Function::ZoneHandle( | 9547 const Function& func = Function::ZoneHandle( |
| 9760 Z, Resolver::ResolveStatic(cls, func_name, kTypeArgsLen, | 9548 Z, Resolver::ResolveStatic(cls, func_name, kTypeArgsLen, |
| 9761 arguments->length(), arguments->names())); | 9549 arguments->length(), arguments->names())); |
| 9762 ASSERT(!func.IsNull()); | 9550 ASSERT(!func.IsNull()); |
| 9763 return new (Z) StaticCallNode(arguments->token_pos(), func, arguments); | 9551 return new (Z) StaticCallNode(arguments->token_pos(), func, arguments); |
| 9764 } | 9552 } |
| 9765 | 9553 |
| 9766 | |
| 9767 AstNode* Parser::ParseAssertStatement(bool is_const) { | 9554 AstNode* Parser::ParseAssertStatement(bool is_const) { |
| 9768 TRACE_PARSER("ParseAssertStatement"); | 9555 TRACE_PARSER("ParseAssertStatement"); |
| 9769 ConsumeToken(); // Consume assert keyword. | 9556 ConsumeToken(); // Consume assert keyword. |
| 9770 ExpectToken(Token::kLPAREN); | 9557 ExpectToken(Token::kLPAREN); |
| 9771 const TokenPosition condition_pos = TokenPos(); | 9558 const TokenPosition condition_pos = TokenPos(); |
| 9772 if (!I->asserts()) { | 9559 if (!I->asserts()) { |
| 9773 SkipExpr(); | 9560 SkipExpr(); |
| 9774 if (CurrentToken() == Token::kCOMMA) { | 9561 if (CurrentToken() == Token::kCOMMA) { |
| 9775 ConsumeToken(); | 9562 ConsumeToken(); |
| 9776 if (CurrentToken() != Token::kRPAREN) { | 9563 if (CurrentToken() != Token::kRPAREN) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9863 assertion_check = preamble; | 9650 assertion_check = preamble; |
| 9864 } else { | 9651 } else { |
| 9865 // Build if (!condition) _AsertionError._throwNew(...) | 9652 // Build if (!condition) _AsertionError._throwNew(...) |
| 9866 assertion_check = new (Z) | 9653 assertion_check = new (Z) |
| 9867 IfNode(condition_pos, not_condition, | 9654 IfNode(condition_pos, not_condition, |
| 9868 NodeAsSequenceNode(condition_pos, assert_throw, NULL), NULL); | 9655 NodeAsSequenceNode(condition_pos, assert_throw, NULL), NULL); |
| 9869 } | 9656 } |
| 9870 return assertion_check; | 9657 return assertion_check; |
| 9871 } | 9658 } |
| 9872 | 9659 |
| 9873 | |
| 9874 // Populate local scope of the catch block with the catch parameters. | 9660 // Populate local scope of the catch block with the catch parameters. |
| 9875 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 9661 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
| 9876 CatchParamDesc* stack_trace_param, | 9662 CatchParamDesc* stack_trace_param, |
| 9877 LocalScope* scope) { | 9663 LocalScope* scope) { |
| 9878 if (exception_param->name != NULL) { | 9664 if (exception_param->name != NULL) { |
| 9879 LocalVariable* var = new (Z) | 9665 LocalVariable* var = new (Z) |
| 9880 LocalVariable(exception_param->token_pos, exception_param->token_pos, | 9666 LocalVariable(exception_param->token_pos, exception_param->token_pos, |
| 9881 *exception_param->name, *exception_param->type); | 9667 *exception_param->name, *exception_param->type); |
| 9882 var->set_is_final(); | 9668 var->set_is_final(); |
| 9883 bool added_to_scope = scope->AddVariable(var); | 9669 bool added_to_scope = scope->AddVariable(var); |
| 9884 ASSERT(added_to_scope); | 9670 ASSERT(added_to_scope); |
| 9885 exception_param->var = var; | 9671 exception_param->var = var; |
| 9886 } | 9672 } |
| 9887 if (stack_trace_param->name != NULL) { | 9673 if (stack_trace_param->name != NULL) { |
| 9888 LocalVariable* var = new (Z) LocalVariable( | 9674 LocalVariable* var = new (Z) LocalVariable( |
| 9889 stack_trace_param->token_pos, stack_trace_param->token_pos, | 9675 stack_trace_param->token_pos, stack_trace_param->token_pos, |
| 9890 *stack_trace_param->name, *stack_trace_param->type); | 9676 *stack_trace_param->name, *stack_trace_param->type); |
| 9891 var->set_is_final(); | 9677 var->set_is_final(); |
| 9892 bool added_to_scope = scope->AddVariable(var); | 9678 bool added_to_scope = scope->AddVariable(var); |
| 9893 if (!added_to_scope) { | 9679 if (!added_to_scope) { |
| 9894 // The name of the exception param is reused for the stack trace param. | 9680 // The name of the exception param is reused for the stack trace param. |
| 9895 ReportError(stack_trace_param->token_pos, | 9681 ReportError(stack_trace_param->token_pos, |
| 9896 "name '%s' already exists in scope", | 9682 "name '%s' already exists in scope", |
| 9897 stack_trace_param->name->ToCString()); | 9683 stack_trace_param->name->ToCString()); |
| 9898 } | 9684 } |
| 9899 stack_trace_param->var = var; | 9685 stack_trace_param->var = var; |
| 9900 } | 9686 } |
| 9901 } | 9687 } |
| 9902 | 9688 |
| 9903 | |
| 9904 // Generate code to load the exception object (:exception_var) into | 9689 // Generate code to load the exception object (:exception_var) into |
| 9905 // the saved exception variable (:saved_exception_var) used to rethrow. | 9690 // the saved exception variable (:saved_exception_var) used to rethrow. |
| 9906 // Generate code to load the stack trace object (:stack_trace_var) into | 9691 // Generate code to load the stack trace object (:stack_trace_var) into |
| 9907 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. | 9692 // the saved stacktrace variable (:saved_stack_trace_var) used to rethrow. |
| 9908 void Parser::SaveExceptionAndStackTrace(SequenceNode* statements, | 9693 void Parser::SaveExceptionAndStackTrace(SequenceNode* statements, |
| 9909 LocalVariable* exception_var, | 9694 LocalVariable* exception_var, |
| 9910 LocalVariable* stack_trace_var, | 9695 LocalVariable* stack_trace_var, |
| 9911 LocalVariable* saved_exception_var, | 9696 LocalVariable* saved_exception_var, |
| 9912 LocalVariable* saved_stack_trace_var) { | 9697 LocalVariable* saved_stack_trace_var) { |
| 9913 ASSERT(innermost_function().IsAsyncClosure() || | 9698 ASSERT(innermost_function().IsAsyncClosure() || |
| 9914 innermost_function().IsAsyncFunction() || | 9699 innermost_function().IsAsyncFunction() || |
| 9915 innermost_function().IsSyncGenClosure() || | 9700 innermost_function().IsSyncGenClosure() || |
| 9916 innermost_function().IsSyncGenerator() || | 9701 innermost_function().IsSyncGenerator() || |
| 9917 innermost_function().IsAsyncGenClosure() || | 9702 innermost_function().IsAsyncGenClosure() || |
| 9918 innermost_function().IsAsyncGenerator()); | 9703 innermost_function().IsAsyncGenerator()); |
| 9919 | 9704 |
| 9920 ASSERT(saved_exception_var != NULL); | 9705 ASSERT(saved_exception_var != NULL); |
| 9921 ASSERT(exception_var != NULL); | 9706 ASSERT(exception_var != NULL); |
| 9922 statements->Add(new (Z) StoreLocalNode( | 9707 statements->Add(new (Z) StoreLocalNode( |
| 9923 TokenPosition::kNoSource, saved_exception_var, | 9708 TokenPosition::kNoSource, saved_exception_var, |
| 9924 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); | 9709 new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_var))); |
| 9925 | 9710 |
| 9926 ASSERT(saved_stack_trace_var != NULL); | 9711 ASSERT(saved_stack_trace_var != NULL); |
| 9927 ASSERT(stack_trace_var != NULL); | 9712 ASSERT(stack_trace_var != NULL); |
| 9928 statements->Add(new (Z) StoreLocalNode( | 9713 statements->Add(new (Z) StoreLocalNode( |
| 9929 TokenPosition::kNoSource, saved_stack_trace_var, | 9714 TokenPosition::kNoSource, saved_stack_trace_var, |
| 9930 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); | 9715 new (Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var))); |
| 9931 } | 9716 } |
| 9932 | 9717 |
| 9933 | |
| 9934 SequenceNode* Parser::EnsureFinallyClause( | 9718 SequenceNode* Parser::EnsureFinallyClause( |
| 9935 bool parse, | 9719 bool parse, |
| 9936 bool is_async, | 9720 bool is_async, |
| 9937 LocalVariable* exception_var, | 9721 LocalVariable* exception_var, |
| 9938 LocalVariable* stack_trace_var, | 9722 LocalVariable* stack_trace_var, |
| 9939 LocalVariable* rethrow_exception_var, | 9723 LocalVariable* rethrow_exception_var, |
| 9940 LocalVariable* rethrow_stack_trace_var) { | 9724 LocalVariable* rethrow_stack_trace_var) { |
| 9941 TRACE_PARSER("EnsureFinallyClause"); | 9725 TRACE_PARSER("EnsureFinallyClause"); |
| 9942 ASSERT(parse || (is_async && (try_stack_ != NULL))); | 9726 ASSERT(parse || (is_async && (try_stack_ != NULL))); |
| 9943 // Increasing the loop level prevents the reuse of a parent context and forces | 9727 // Increasing the loop level prevents the reuse of a parent context and forces |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9987 ParseStatementSequence(); | 9771 ParseStatementSequence(); |
| 9988 ExpectToken(Token::kRBRACE); | 9772 ExpectToken(Token::kRBRACE); |
| 9989 } | 9773 } |
| 9990 SequenceNode* finally_clause = CloseBlock(); | 9774 SequenceNode* finally_clause = CloseBlock(); |
| 9991 if (try_stack_ != NULL) { | 9775 if (try_stack_ != NULL) { |
| 9992 try_stack_->exit_finally(); | 9776 try_stack_->exit_finally(); |
| 9993 } | 9777 } |
| 9994 return finally_clause; | 9778 return finally_clause; |
| 9995 } | 9779 } |
| 9996 | 9780 |
| 9997 | |
| 9998 void Parser::PushTry(Block* try_block) { | 9781 void Parser::PushTry(Block* try_block) { |
| 9999 intptr_t try_index = AllocateTryIndex(); | 9782 intptr_t try_index = AllocateTryIndex(); |
| 10000 try_stack_ = new (Z) TryStack(try_block, try_stack_, try_index); | 9783 try_stack_ = new (Z) TryStack(try_block, try_stack_, try_index); |
| 10001 } | 9784 } |
| 10002 | 9785 |
| 10003 | |
| 10004 Parser::TryStack* Parser::PopTry() { | 9786 Parser::TryStack* Parser::PopTry() { |
| 10005 TryStack* innermost_try = try_stack_; | 9787 TryStack* innermost_try = try_stack_; |
| 10006 try_stack_ = try_stack_->outer_try(); | 9788 try_stack_ = try_stack_->outer_try(); |
| 10007 return innermost_try; | 9789 return innermost_try; |
| 10008 } | 9790 } |
| 10009 | 9791 |
| 10010 | |
| 10011 void Parser::AddNodeForFinallyInlining(AstNode* node) { | 9792 void Parser::AddNodeForFinallyInlining(AstNode* node) { |
| 10012 if (node == NULL) { | 9793 if (node == NULL) { |
| 10013 return; | 9794 return; |
| 10014 } | 9795 } |
| 10015 ASSERT(node->IsReturnNode() || node->IsJumpNode()); | 9796 ASSERT(node->IsReturnNode() || node->IsJumpNode()); |
| 10016 const intptr_t func_level = FunctionLevel(); | 9797 const intptr_t func_level = FunctionLevel(); |
| 10017 TryStack* iterator = try_stack_; | 9798 TryStack* iterator = try_stack_; |
| 10018 while ((iterator != NULL) && | 9799 while ((iterator != NULL) && |
| 10019 (iterator->try_block()->scope->function_level() == func_level)) { | 9800 (iterator->try_block()->scope->function_level() == func_level)) { |
| 10020 // For continue and break node check if the target label is in scope. | 9801 // For continue and break node check if the target label is in scope. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 10034 // RemoveNodesForFinallyInlining below.) | 9815 // RemoveNodesForFinallyInlining below.) |
| 10035 if (!label->IsUnresolved() && label->owner()->IsNestedWithin(try_scope)) { | 9816 if (!label->IsUnresolved() && label->owner()->IsNestedWithin(try_scope)) { |
| 10036 break; | 9817 break; |
| 10037 } | 9818 } |
| 10038 } | 9819 } |
| 10039 iterator->AddNodeForFinallyInlining(node); | 9820 iterator->AddNodeForFinallyInlining(node); |
| 10040 iterator = iterator->outer_try(); | 9821 iterator = iterator->outer_try(); |
| 10041 } | 9822 } |
| 10042 } | 9823 } |
| 10043 | 9824 |
| 10044 | |
| 10045 void Parser::RemoveNodesForFinallyInlining(SourceLabel* label) { | 9825 void Parser::RemoveNodesForFinallyInlining(SourceLabel* label) { |
| 10046 TryStack* iterator = try_stack_; | 9826 TryStack* iterator = try_stack_; |
| 10047 const intptr_t func_level = FunctionLevel(); | 9827 const intptr_t func_level = FunctionLevel(); |
| 10048 while ((iterator != NULL) && | 9828 while ((iterator != NULL) && |
| 10049 (iterator->try_block()->scope->function_level() == func_level)) { | 9829 (iterator->try_block()->scope->function_level() == func_level)) { |
| 10050 iterator->RemoveJumpToLabel(label); | 9830 iterator->RemoveJumpToLabel(label); |
| 10051 iterator = iterator->outer_try(); | 9831 iterator = iterator->outer_try(); |
| 10052 } | 9832 } |
| 10053 } | 9833 } |
| 10054 | 9834 |
| 10055 | |
| 10056 // Add the inlined finally clause to the specified node. | 9835 // Add the inlined finally clause to the specified node. |
| 10057 void Parser::AddFinallyClauseToNode(bool is_async, | 9836 void Parser::AddFinallyClauseToNode(bool is_async, |
| 10058 AstNode* node, | 9837 AstNode* node, |
| 10059 InlinedFinallyNode* finally_clause) { | 9838 InlinedFinallyNode* finally_clause) { |
| 10060 ReturnNode* return_node = node->AsReturnNode(); | 9839 ReturnNode* return_node = node->AsReturnNode(); |
| 10061 if (return_node != NULL) { | 9840 if (return_node != NULL) { |
| 10062 if (FunctionLevel() == 0) { | 9841 if (FunctionLevel() == 0) { |
| 10063 parsed_function()->EnsureFinallyReturnTemp(is_async); | 9842 parsed_function()->EnsureFinallyReturnTemp(is_async); |
| 10064 } | 9843 } |
| 10065 return_node->AddInlinedFinallyNode(finally_clause); | 9844 return_node->AddInlinedFinallyNode(finally_clause); |
| 10066 return; | 9845 return; |
| 10067 } | 9846 } |
| 10068 JumpNode* jump_node = node->AsJumpNode(); | 9847 JumpNode* jump_node = node->AsJumpNode(); |
| 10069 ASSERT(jump_node != NULL); | 9848 ASSERT(jump_node != NULL); |
| 10070 jump_node->AddInlinedFinallyNode(finally_clause); | 9849 jump_node->AddInlinedFinallyNode(finally_clause); |
| 10071 } | 9850 } |
| 10072 | 9851 |
| 10073 | |
| 10074 SequenceNode* Parser::ParseCatchClauses( | 9852 SequenceNode* Parser::ParseCatchClauses( |
| 10075 TokenPosition handler_pos, | 9853 TokenPosition handler_pos, |
| 10076 bool is_async, | 9854 bool is_async, |
| 10077 LocalVariable* exception_var, | 9855 LocalVariable* exception_var, |
| 10078 LocalVariable* stack_trace_var, | 9856 LocalVariable* stack_trace_var, |
| 10079 LocalVariable* rethrow_exception_var, | 9857 LocalVariable* rethrow_exception_var, |
| 10080 LocalVariable* rethrow_stack_trace_var, | 9858 LocalVariable* rethrow_stack_trace_var, |
| 10081 const GrowableObjectArray& handler_types, | 9859 const GrowableObjectArray& handler_types, |
| 10082 bool* needs_stack_trace) { | 9860 bool* needs_stack_trace) { |
| 10083 // All catch blocks are merged into an if-then-else sequence of the | 9861 // All catch blocks are merged into an if-then-else sequence of the |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10265 // an outer try block is present) and code to save the exception and | 10043 // an outer try block is present) and code to save the exception and |
| 10266 // stack trace variables. | 10044 // stack trace variables. |
| 10267 // This async code is inserted before the current node sequence containing | 10045 // This async code is inserted before the current node sequence containing |
| 10268 // the chain of if/then/else handling all catch clauses. | 10046 // the chain of if/then/else handling all catch clauses. |
| 10269 async_code->Add(current); | 10047 async_code->Add(current); |
| 10270 current = async_code; | 10048 current = async_code; |
| 10271 } | 10049 } |
| 10272 return current; | 10050 return current; |
| 10273 } | 10051 } |
| 10274 | 10052 |
| 10275 | |
| 10276 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 10053 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
| 10277 const String& async_saved_try_ctx_name = String::ZoneHandle( | 10054 const String& async_saved_try_ctx_name = String::ZoneHandle( |
| 10278 Z, Symbols::NewFormatted(T, "%s%d", | 10055 Z, Symbols::NewFormatted(T, "%s%d", |
| 10279 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 10056 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
| 10280 last_used_try_index_ - 1)); | 10057 last_used_try_index_ - 1)); |
| 10281 LocalVariable* async_saved_try_ctx = | 10058 LocalVariable* async_saved_try_ctx = |
| 10282 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 10059 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 10283 async_saved_try_ctx_name, Object::dynamic_type()); | 10060 async_saved_try_ctx_name, Object::dynamic_type()); |
| 10284 ASSERT(async_temp_scope_ != NULL); | 10061 ASSERT(async_temp_scope_ != NULL); |
| 10285 async_temp_scope_->AddVariable(async_saved_try_ctx); | 10062 async_temp_scope_->AddVariable(async_saved_try_ctx); |
| 10286 ASSERT(saved_try_context != NULL); | 10063 ASSERT(saved_try_context != NULL); |
| 10287 current_block_->statements->Add(new (Z) StoreLocalNode( | 10064 current_block_->statements->Add(new (Z) StoreLocalNode( |
| 10288 TokenPosition::kNoSource, async_saved_try_ctx, | 10065 TokenPosition::kNoSource, async_saved_try_ctx, |
| 10289 new (Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); | 10066 new (Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context))); |
| 10290 } | 10067 } |
| 10291 | 10068 |
| 10292 | |
| 10293 // We create three variables for exceptions: | 10069 // We create three variables for exceptions: |
| 10294 // ':saved_try_context_var' - Used to save the context before the start of | 10070 // ':saved_try_context_var' - Used to save the context before the start of |
| 10295 // the try block. The context register is | 10071 // the try block. The context register is |
| 10296 // restored from this variable before | 10072 // restored from this variable before |
| 10297 // processing the catch block handler. | 10073 // processing the catch block handler. |
| 10298 // ':exception_var' - Used to save the current exception object that was | 10074 // ':exception_var' - Used to save the current exception object that was |
| 10299 // thrown. | 10075 // thrown. |
| 10300 // ':stack_trace_var' - Used to save the current stack trace object which | 10076 // ':stack_trace_var' - Used to save the current stack trace object which |
| 10301 // the stack trace was copied into when an exception | 10077 // the stack trace was copied into when an exception |
| 10302 // was thrown. | 10078 // was thrown. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10349 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); | 10125 try_scope->LocalLookupVariable(Symbols::SavedStackTraceVar()); |
| 10350 if (*saved_stack_trace_var == NULL) { | 10126 if (*saved_stack_trace_var == NULL) { |
| 10351 *saved_stack_trace_var = new (Z) | 10127 *saved_stack_trace_var = new (Z) |
| 10352 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedStackTraceVar(), | 10128 LocalVariable(TokenPos(), TokenPos(), Symbols::SavedStackTraceVar(), |
| 10353 Object::dynamic_type()); | 10129 Object::dynamic_type()); |
| 10354 try_scope->AddVariable(*saved_stack_trace_var); | 10130 try_scope->AddVariable(*saved_stack_trace_var); |
| 10355 } | 10131 } |
| 10356 } | 10132 } |
| 10357 } | 10133 } |
| 10358 | 10134 |
| 10359 | |
| 10360 AstNode* Parser::ParseTryStatement(String* label_name) { | 10135 AstNode* Parser::ParseTryStatement(String* label_name) { |
| 10361 TRACE_PARSER("ParseTryStatement"); | 10136 TRACE_PARSER("ParseTryStatement"); |
| 10362 | 10137 |
| 10363 const TokenPosition try_pos = TokenPos(); | 10138 const TokenPosition try_pos = TokenPos(); |
| 10364 SourceLabel* try_label = NULL; | 10139 SourceLabel* try_label = NULL; |
| 10365 if (label_name != NULL) { | 10140 if (label_name != NULL) { |
| 10366 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 10141 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 10367 OpenBlock(); | 10142 OpenBlock(); |
| 10368 current_block_->scope->AddLabel(try_label); | 10143 current_block_->scope->AddLabel(try_label); |
| 10369 } | 10144 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10487 if (try_label != NULL) { | 10262 if (try_label != NULL) { |
| 10488 current_block_->statements->Add(try_catch_node); | 10263 current_block_->statements->Add(try_catch_node); |
| 10489 SequenceNode* sequence = CloseBlock(); | 10264 SequenceNode* sequence = CloseBlock(); |
| 10490 sequence->set_label(try_label); | 10265 sequence->set_label(try_label); |
| 10491 try_catch_node = sequence; | 10266 try_catch_node = sequence; |
| 10492 } | 10267 } |
| 10493 | 10268 |
| 10494 return try_catch_node; | 10269 return try_catch_node; |
| 10495 } | 10270 } |
| 10496 | 10271 |
| 10497 | |
| 10498 AstNode* Parser::ParseJump(String* label_name) { | 10272 AstNode* Parser::ParseJump(String* label_name) { |
| 10499 TRACE_PARSER("ParseJump"); | 10273 TRACE_PARSER("ParseJump"); |
| 10500 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 10274 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 10501 Token::Kind jump_kind = CurrentToken(); | 10275 Token::Kind jump_kind = CurrentToken(); |
| 10502 const TokenPosition jump_pos = TokenPos(); | 10276 const TokenPosition jump_pos = TokenPos(); |
| 10503 SourceLabel* target = NULL; | 10277 SourceLabel* target = NULL; |
| 10504 ConsumeToken(); | 10278 ConsumeToken(); |
| 10505 if (IsIdentifier()) { | 10279 if (IsIdentifier()) { |
| 10506 // Explicit label after break/continue. | 10280 // Explicit label after break/continue. |
| 10507 const String& target_name = *CurrentLiteral(); | 10281 const String& target_name = *CurrentLiteral(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10554 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { | 10328 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { |
| 10555 ReportError(jump_pos, "'break' to case clause label is illegal"); | 10329 ReportError(jump_pos, "'break' to case clause label is illegal"); |
| 10556 } | 10330 } |
| 10557 if (target->FunctionLevel() != FunctionLevel()) { | 10331 if (target->FunctionLevel() != FunctionLevel()) { |
| 10558 ReportError(jump_pos, "'%s' target must be in same function context", | 10332 ReportError(jump_pos, "'%s' target must be in same function context", |
| 10559 Token::Str(jump_kind)); | 10333 Token::Str(jump_kind)); |
| 10560 } | 10334 } |
| 10561 return new (Z) JumpNode(jump_pos, jump_kind, target); | 10335 return new (Z) JumpNode(jump_pos, jump_kind, target); |
| 10562 } | 10336 } |
| 10563 | 10337 |
| 10564 | |
| 10565 AstNode* Parser::ParseYieldStatement() { | 10338 AstNode* Parser::ParseYieldStatement() { |
| 10566 bool is_yield_each = false; | 10339 bool is_yield_each = false; |
| 10567 const TokenPosition yield_pos = TokenPos(); | 10340 const TokenPosition yield_pos = TokenPos(); |
| 10568 ConsumeToken(); // yield reserved word. | 10341 ConsumeToken(); // yield reserved word. |
| 10569 if (CurrentToken() == Token::kMUL) { | 10342 if (CurrentToken() == Token::kMUL) { |
| 10570 is_yield_each = true; | 10343 is_yield_each = true; |
| 10571 ConsumeToken(); | 10344 ConsumeToken(); |
| 10572 } | 10345 } |
| 10573 if (!innermost_function().IsGenerator() && | 10346 if (!innermost_function().IsGenerator() && |
| 10574 !innermost_function().IsGeneratorClosure()) { | 10347 !innermost_function().IsGeneratorClosure()) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10693 new (Z) LoadLocalNode(TokenPosition::kNoSource, | 10466 new (Z) LoadLocalNode(TokenPosition::kNoSource, |
| 10694 outer_async_saved_try_ctx))); | 10467 outer_async_saved_try_ctx))); |
| 10695 } | 10468 } |
| 10696 } else { | 10469 } else { |
| 10697 ASSERT(outer_saved_try_ctx == NULL); | 10470 ASSERT(outer_saved_try_ctx == NULL); |
| 10698 } | 10471 } |
| 10699 } | 10472 } |
| 10700 return yield; | 10473 return yield; |
| 10701 } | 10474 } |
| 10702 | 10475 |
| 10703 | |
| 10704 AstNode* Parser::ParseStatement() { | 10476 AstNode* Parser::ParseStatement() { |
| 10705 TRACE_PARSER("ParseStatement"); | 10477 TRACE_PARSER("ParseStatement"); |
| 10706 AstNode* statement = NULL; | 10478 AstNode* statement = NULL; |
| 10707 TokenPosition label_pos = TokenPosition::kNoSource; | 10479 TokenPosition label_pos = TokenPosition::kNoSource; |
| 10708 String* label_name = NULL; | 10480 String* label_name = NULL; |
| 10709 if (IsIdentifier()) { | 10481 if (IsIdentifier()) { |
| 10710 if (LookaheadToken(1) == Token::kCOLON) { | 10482 if (LookaheadToken(1) == Token::kCOLON) { |
| 10711 // Statement starts with a label. | 10483 // Statement starts with a label. |
| 10712 label_name = CurrentLiteral(); | 10484 label_name = CurrentLiteral(); |
| 10713 label_pos = TokenPos(); | 10485 label_pos = TokenPos(); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10881 statement = new (Z) | 10653 statement = new (Z) |
| 10882 ThrowNode(statement_pos, new (Z) LoadLocalNode(statement_pos, excp_var), | 10654 ThrowNode(statement_pos, new (Z) LoadLocalNode(statement_pos, excp_var), |
| 10883 new (Z) LoadLocalNode(statement_pos, trace_var)); | 10655 new (Z) LoadLocalNode(statement_pos, trace_var)); |
| 10884 } else { | 10656 } else { |
| 10885 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 10657 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 10886 ExpectSemicolon(); | 10658 ExpectSemicolon(); |
| 10887 } | 10659 } |
| 10888 return statement; | 10660 return statement; |
| 10889 } | 10661 } |
| 10890 | 10662 |
| 10891 | |
| 10892 void Parser::ReportError(const Error& error) { | 10663 void Parser::ReportError(const Error& error) { |
| 10893 Report::LongJump(error); | 10664 Report::LongJump(error); |
| 10894 UNREACHABLE(); | 10665 UNREACHABLE(); |
| 10895 } | 10666 } |
| 10896 | 10667 |
| 10897 | |
| 10898 void Parser::ReportErrors(const Error& prev_error, | 10668 void Parser::ReportErrors(const Error& prev_error, |
| 10899 const Script& script, | 10669 const Script& script, |
| 10900 TokenPosition token_pos, | 10670 TokenPosition token_pos, |
| 10901 const char* format, | 10671 const char* format, |
| 10902 ...) { | 10672 ...) { |
| 10903 va_list args; | 10673 va_list args; |
| 10904 va_start(args, format); | 10674 va_start(args, format); |
| 10905 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10675 Report::LongJumpV(prev_error, script, token_pos, format, args); |
| 10906 va_end(args); | 10676 va_end(args); |
| 10907 UNREACHABLE(); | 10677 UNREACHABLE(); |
| 10908 } | 10678 } |
| 10909 | 10679 |
| 10910 | |
| 10911 void Parser::ReportError(TokenPosition token_pos, | 10680 void Parser::ReportError(TokenPosition token_pos, |
| 10912 const char* format, | 10681 const char* format, |
| 10913 ...) const { | 10682 ...) const { |
| 10914 va_list args; | 10683 va_list args; |
| 10915 va_start(args, format); | 10684 va_start(args, format); |
| 10916 Report::MessageV(Report::kError, script_, token_pos, Report::AtLocation, | 10685 Report::MessageV(Report::kError, script_, token_pos, Report::AtLocation, |
| 10917 format, args); | 10686 format, args); |
| 10918 va_end(args); | 10687 va_end(args); |
| 10919 UNREACHABLE(); | 10688 UNREACHABLE(); |
| 10920 } | 10689 } |
| 10921 | 10690 |
| 10922 | |
| 10923 void Parser::ReportErrorBefore(const char* format, ...) { | 10691 void Parser::ReportErrorBefore(const char* format, ...) { |
| 10924 va_list args; | 10692 va_list args; |
| 10925 va_start(args, format); | 10693 va_start(args, format); |
| 10926 Report::MessageV(Report::kError, script_, PrevTokenPos(), | 10694 Report::MessageV(Report::kError, script_, PrevTokenPos(), |
| 10927 Report::AfterLocation, format, args); | 10695 Report::AfterLocation, format, args); |
| 10928 va_end(args); | 10696 va_end(args); |
| 10929 UNREACHABLE(); | 10697 UNREACHABLE(); |
| 10930 } | 10698 } |
| 10931 | 10699 |
| 10932 | |
| 10933 void Parser::ReportError(const char* format, ...) const { | 10700 void Parser::ReportError(const char* format, ...) const { |
| 10934 va_list args; | 10701 va_list args; |
| 10935 va_start(args, format); | 10702 va_start(args, format); |
| 10936 Report::MessageV(Report::kError, script_, TokenPos(), Report::AtLocation, | 10703 Report::MessageV(Report::kError, script_, TokenPos(), Report::AtLocation, |
| 10937 format, args); | 10704 format, args); |
| 10938 va_end(args); | 10705 va_end(args); |
| 10939 UNREACHABLE(); | 10706 UNREACHABLE(); |
| 10940 } | 10707 } |
| 10941 | 10708 |
| 10942 | |
| 10943 void Parser::ReportWarning(TokenPosition token_pos, | 10709 void Parser::ReportWarning(TokenPosition token_pos, |
| 10944 const char* format, | 10710 const char* format, |
| 10945 ...) const { | 10711 ...) const { |
| 10946 va_list args; | 10712 va_list args; |
| 10947 va_start(args, format); | 10713 va_start(args, format); |
| 10948 Report::MessageV(Report::kWarning, script_, token_pos, Report::AtLocation, | 10714 Report::MessageV(Report::kWarning, script_, token_pos, Report::AtLocation, |
| 10949 format, args); | 10715 format, args); |
| 10950 va_end(args); | 10716 va_end(args); |
| 10951 } | 10717 } |
| 10952 | 10718 |
| 10953 | |
| 10954 void Parser::ReportWarning(const char* format, ...) const { | 10719 void Parser::ReportWarning(const char* format, ...) const { |
| 10955 va_list args; | 10720 va_list args; |
| 10956 va_start(args, format); | 10721 va_start(args, format); |
| 10957 Report::MessageV(Report::kWarning, script_, TokenPos(), Report::AtLocation, | 10722 Report::MessageV(Report::kWarning, script_, TokenPos(), Report::AtLocation, |
| 10958 format, args); | 10723 format, args); |
| 10959 va_end(args); | 10724 va_end(args); |
| 10960 } | 10725 } |
| 10961 | 10726 |
| 10962 | |
| 10963 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { | 10727 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { |
| 10964 if (CurrentToken() != token_expected) { | 10728 if (CurrentToken() != token_expected) { |
| 10965 if (msg != NULL) { | 10729 if (msg != NULL) { |
| 10966 ReportError("%s", msg); | 10730 ReportError("%s", msg); |
| 10967 } else { | 10731 } else { |
| 10968 ReportError("'%s' expected", Token::Str(token_expected)); | 10732 ReportError("'%s' expected", Token::Str(token_expected)); |
| 10969 } | 10733 } |
| 10970 } | 10734 } |
| 10971 } | 10735 } |
| 10972 | 10736 |
| 10973 | |
| 10974 void Parser::ExpectToken(Token::Kind token_expected) { | 10737 void Parser::ExpectToken(Token::Kind token_expected) { |
| 10975 if (CurrentToken() != token_expected) { | 10738 if (CurrentToken() != token_expected) { |
| 10976 ReportError("'%s' expected", Token::Str(token_expected)); | 10739 ReportError("'%s' expected", Token::Str(token_expected)); |
| 10977 } | 10740 } |
| 10978 ConsumeToken(); | 10741 ConsumeToken(); |
| 10979 } | 10742 } |
| 10980 | 10743 |
| 10981 | |
| 10982 void Parser::ExpectSemicolon() { | 10744 void Parser::ExpectSemicolon() { |
| 10983 if (CurrentToken() != Token::kSEMICOLON) { | 10745 if (CurrentToken() != Token::kSEMICOLON) { |
| 10984 ReportErrorBefore("semicolon expected"); | 10746 ReportErrorBefore("semicolon expected"); |
| 10985 } | 10747 } |
| 10986 ConsumeToken(); | 10748 ConsumeToken(); |
| 10987 } | 10749 } |
| 10988 | 10750 |
| 10989 | |
| 10990 void Parser::UnexpectedToken() { | 10751 void Parser::UnexpectedToken() { |
| 10991 ReportError("unexpected token '%s'", CurrentToken() == Token::kIDENT | 10752 ReportError("unexpected token '%s'", CurrentToken() == Token::kIDENT |
| 10992 ? CurrentLiteral()->ToCString() | 10753 ? CurrentLiteral()->ToCString() |
| 10993 : Token::Str(CurrentToken())); | 10754 : Token::Str(CurrentToken())); |
| 10994 } | 10755 } |
| 10995 | 10756 |
| 10996 | |
| 10997 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { | 10757 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { |
| 10998 if (CurrentToken() != Token::kIDENT) { | 10758 if (CurrentToken() != Token::kIDENT) { |
| 10999 ReportError("%s", msg); | 10759 ReportError("%s", msg); |
| 11000 } | 10760 } |
| 11001 String* ident = CurrentLiteral(); | 10761 String* ident = CurrentLiteral(); |
| 11002 if (ident->Equals("dynamic")) { | 10762 if (ident->Equals("dynamic")) { |
| 11003 ReportError("%s", msg); | 10763 ReportError("%s", msg); |
| 11004 } | 10764 } |
| 11005 ConsumeToken(); | 10765 ConsumeToken(); |
| 11006 return ident; | 10766 return ident; |
| 11007 } | 10767 } |
| 11008 | 10768 |
| 11009 | |
| 11010 // Check whether current token is an identifier or a built-in identifier. | 10769 // Check whether current token is an identifier or a built-in identifier. |
| 11011 String* Parser::ExpectIdentifier(const char* msg) { | 10770 String* Parser::ExpectIdentifier(const char* msg) { |
| 11012 if (!IsIdentifier()) { | 10771 if (!IsIdentifier()) { |
| 11013 ReportError("%s", msg); | 10772 ReportError("%s", msg); |
| 11014 } | 10773 } |
| 11015 String* ident = CurrentLiteral(); | 10774 String* ident = CurrentLiteral(); |
| 11016 ConsumeToken(); | 10775 ConsumeToken(); |
| 11017 return ident; | 10776 return ident; |
| 11018 } | 10777 } |
| 11019 | 10778 |
| 11020 | |
| 11021 bool Parser::IsAwaitKeyword() { | 10779 bool Parser::IsAwaitKeyword() { |
| 11022 return (FLAG_await_is_keyword || await_is_keyword_) && | 10780 return (FLAG_await_is_keyword || await_is_keyword_) && |
| 11023 IsSymbol(Symbols::Await()); | 10781 IsSymbol(Symbols::Await()); |
| 11024 } | 10782 } |
| 11025 | 10783 |
| 11026 | |
| 11027 bool Parser::IsYieldKeyword() { | 10784 bool Parser::IsYieldKeyword() { |
| 11028 return (FLAG_await_is_keyword || await_is_keyword_) && | 10785 return (FLAG_await_is_keyword || await_is_keyword_) && |
| 11029 IsSymbol(Symbols::YieldKw()); | 10786 IsSymbol(Symbols::YieldKw()); |
| 11030 } | 10787 } |
| 11031 | 10788 |
| 11032 | |
| 11033 static bool IsIncrementOperator(Token::Kind token) { | 10789 static bool IsIncrementOperator(Token::Kind token) { |
| 11034 return token == Token::kINCR || token == Token::kDECR; | 10790 return token == Token::kINCR || token == Token::kDECR; |
| 11035 } | 10791 } |
| 11036 | 10792 |
| 11037 | |
| 11038 static bool IsPrefixOperator(Token::Kind token) { | 10793 static bool IsPrefixOperator(Token::Kind token) { |
| 11039 return (token == Token::kSUB) || (token == Token::kNOT) || | 10794 return (token == Token::kSUB) || (token == Token::kNOT) || |
| 11040 (token == Token::kBIT_NOT); | 10795 (token == Token::kBIT_NOT); |
| 11041 } | 10796 } |
| 11042 | 10797 |
| 11043 | |
| 11044 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, | 10798 SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos, |
| 11045 AstNode* node, | 10799 AstNode* node, |
| 11046 LocalScope* scope) { | 10800 LocalScope* scope) { |
| 11047 if ((node == NULL) || !node->IsSequenceNode()) { | 10801 if ((node == NULL) || !node->IsSequenceNode()) { |
| 11048 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); | 10802 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); |
| 11049 if (node != NULL) { | 10803 if (node != NULL) { |
| 11050 sequence->Add(node); | 10804 sequence->Add(node); |
| 11051 } | 10805 } |
| 11052 return sequence; | 10806 return sequence; |
| 11053 } | 10807 } |
| 11054 return node->AsSequenceNode(); | 10808 return node->AsSequenceNode(); |
| 11055 } | 10809 } |
| 11056 | 10810 |
| 11057 | |
| 11058 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10811 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
| 11059 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, | 10812 AstNode* Parser::ThrowTypeError(TokenPosition type_pos, |
| 11060 const AbstractType& type, | 10813 const AbstractType& type, |
| 11061 LibraryPrefix* prefix) { | 10814 LibraryPrefix* prefix) { |
| 11062 ArgumentListNode* arguments = new (Z) ArgumentListNode(type_pos); | 10815 ArgumentListNode* arguments = new (Z) ArgumentListNode(type_pos); |
| 11063 | 10816 |
| 11064 String& method_name = String::Handle(Z); | 10817 String& method_name = String::Handle(Z); |
| 11065 if (prefix == NULL) { | 10818 if (prefix == NULL) { |
| 11066 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10819 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
| 11067 } else { | 10820 } else { |
| 11068 arguments->Add(new (Z) LiteralNode(type_pos, *prefix)); | 10821 arguments->Add(new (Z) LiteralNode(type_pos, *prefix)); |
| 11069 method_name = | 10822 method_name = |
| 11070 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); | 10823 Library::PrivateCoreLibName(Symbols::ThrowNewIfNotLoaded()).raw(); |
| 11071 } | 10824 } |
| 11072 // Location argument. | 10825 // Location argument. |
| 11073 arguments->Add(new (Z) LiteralNode( | 10826 arguments->Add(new (Z) LiteralNode( |
| 11074 type_pos, | 10827 type_pos, |
| 11075 Integer::ZoneHandle(Z, Integer::New(type_pos.value(), Heap::kOld)))); | 10828 Integer::ZoneHandle(Z, Integer::New(type_pos.value(), Heap::kOld)))); |
| 11076 // Src value argument. | 10829 // Src value argument. |
| 11077 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); | 10830 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); |
| 11078 // Dst type argument. | 10831 // Dst type argument. |
| 11079 arguments->Add(new (Z) LiteralNode(type_pos, type)); | 10832 arguments->Add(new (Z) LiteralNode(type_pos, type)); |
| 11080 // Dst name argument. | 10833 // Dst name argument. |
| 11081 arguments->Add(new (Z) LiteralNode(type_pos, Symbols::Empty())); | 10834 arguments->Add(new (Z) LiteralNode(type_pos, Symbols::Empty())); |
| 11082 // Bound error msg argument. | 10835 // Bound error msg argument. |
| 11083 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); | 10836 arguments->Add(new (Z) LiteralNode(type_pos, Object::null_instance())); |
| 11084 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); | 10837 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); |
| 11085 } | 10838 } |
| 11086 | 10839 |
| 11087 | |
| 11088 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10840 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
| 11089 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, | 10841 AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos, |
| 11090 const Class& cls, | 10842 const Class& cls, |
| 11091 const String& function_name, | 10843 const String& function_name, |
| 11092 ArgumentListNode* function_arguments, | 10844 ArgumentListNode* function_arguments, |
| 11093 InvocationMirror::Call im_call, | 10845 InvocationMirror::Call im_call, |
| 11094 InvocationMirror::Type im_type, | 10846 InvocationMirror::Type im_type, |
| 11095 const Function* func, | 10847 const Function* func, |
| 11096 const LibraryPrefix* prefix) { | 10848 const LibraryPrefix* prefix) { |
| 11097 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos); | 10849 ArgumentListNode* arguments = new (Z) ArgumentListNode(call_pos); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11171 // between dart2js and VM. Update the constructor to accept a string | 10923 // between dart2js and VM. Update the constructor to accept a string |
| 11172 // describing the formal parameters of an incompatible call target. | 10924 // describing the formal parameters of an incompatible call target. |
| 11173 array = Array::New(1, Heap::kOld); | 10925 array = Array::New(1, Heap::kOld); |
| 11174 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); | 10926 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); |
| 11175 } | 10927 } |
| 11176 arguments->Add(new (Z) LiteralNode(call_pos, array)); | 10928 arguments->Add(new (Z) LiteralNode(call_pos, array)); |
| 11177 | 10929 |
| 11178 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); | 10930 return MakeStaticCall(Symbols::NoSuchMethodError(), method_name, arguments); |
| 11179 } | 10931 } |
| 11180 | 10932 |
| 11181 | |
| 11182 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 10933 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 11183 TRACE_PARSER("ParseBinaryExpr"); | 10934 TRACE_PARSER("ParseBinaryExpr"); |
| 11184 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10935 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
| 11185 AstNode* left_operand = ParseUnaryExpr(); | 10936 AstNode* left_operand = ParseUnaryExpr(); |
| 11186 if (left_operand->IsPrimaryNode() && | 10937 if (left_operand->IsPrimaryNode() && |
| 11187 (left_operand->AsPrimaryNode()->IsSuper())) { | 10938 (left_operand->AsPrimaryNode()->IsSuper())) { |
| 11188 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10939 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
| 11189 } | 10940 } |
| 11190 int current_preced = Token::Precedence(CurrentToken()); | 10941 int current_preced = Token::Precedence(CurrentToken()); |
| 11191 while (current_preced >= min_preced) { | 10942 while (current_preced >= min_preced) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11234 } else { | 10985 } else { |
| 11235 left_operand = | 10986 left_operand = |
| 11236 OptimizeBinaryOpNode(op_pos, op_kind, left_operand, right_operand); | 10987 OptimizeBinaryOpNode(op_pos, op_kind, left_operand, right_operand); |
| 11237 } | 10988 } |
| 11238 } | 10989 } |
| 11239 current_preced--; | 10990 current_preced--; |
| 11240 } | 10991 } |
| 11241 return left_operand; | 10992 return left_operand; |
| 11242 } | 10993 } |
| 11243 | 10994 |
| 11244 | |
| 11245 AstNode* Parser::ParseAwaitableExprList() { | 10995 AstNode* Parser::ParseAwaitableExprList() { |
| 11246 TRACE_PARSER("ParseAwaitableExprList"); | 10996 TRACE_PARSER("ParseAwaitableExprList"); |
| 11247 SequenceNode* preamble = NULL; | 10997 SequenceNode* preamble = NULL; |
| 11248 AstNode* expressions = | 10998 AstNode* expressions = |
| 11249 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); | 10999 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); |
| 11250 if (preamble != NULL) { | 11000 if (preamble != NULL) { |
| 11251 preamble->Add(expressions); | 11001 preamble->Add(expressions); |
| 11252 expressions = preamble; | 11002 expressions = preamble; |
| 11253 } | 11003 } |
| 11254 if (CurrentToken() == Token::kCOMMA) { | 11004 if (CurrentToken() == Token::kCOMMA) { |
| 11255 // Collect comma-separated expressions in a non scope owning sequence node. | 11005 // Collect comma-separated expressions in a non scope owning sequence node. |
| 11256 SequenceNode* list = new (Z) SequenceNode(TokenPos(), NULL); | 11006 SequenceNode* list = new (Z) SequenceNode(TokenPos(), NULL); |
| 11257 list->Add(expressions); | 11007 list->Add(expressions); |
| 11258 while (CurrentToken() == Token::kCOMMA) { | 11008 while (CurrentToken() == Token::kCOMMA) { |
| 11259 ConsumeToken(); | 11009 ConsumeToken(); |
| 11260 preamble = NULL; | 11010 preamble = NULL; |
| 11261 AstNode* expr = | 11011 AstNode* expr = |
| 11262 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); | 11012 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &preamble); |
| 11263 if (preamble != NULL) { | 11013 if (preamble != NULL) { |
| 11264 list->Add(preamble); | 11014 list->Add(preamble); |
| 11265 } | 11015 } |
| 11266 list->Add(expr); | 11016 list->Add(expr); |
| 11267 } | 11017 } |
| 11268 expressions = list; | 11018 expressions = list; |
| 11269 } | 11019 } |
| 11270 return expressions; | 11020 return expressions; |
| 11271 } | 11021 } |
| 11272 | 11022 |
| 11273 | |
| 11274 void Parser::EnsureExpressionTemp() { | 11023 void Parser::EnsureExpressionTemp() { |
| 11275 // Temporary used later by the flow_graph_builder. | 11024 // Temporary used later by the flow_graph_builder. |
| 11276 parsed_function()->EnsureExpressionTemp(); | 11025 parsed_function()->EnsureExpressionTemp(); |
| 11277 } | 11026 } |
| 11278 | 11027 |
| 11279 | |
| 11280 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, | 11028 LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos, |
| 11281 const char* s) { | 11029 const char* s) { |
| 11282 char name[64]; | 11030 char name[64]; |
| 11283 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); | 11031 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); |
| 11284 LocalVariable* temp = new (Z) LocalVariable( | 11032 LocalVariable* temp = new (Z) LocalVariable( |
| 11285 token_pos, token_pos, String::ZoneHandle(Z, Symbols::New(T, name)), | 11033 token_pos, token_pos, String::ZoneHandle(Z, Symbols::New(T, name)), |
| 11286 Object::dynamic_type()); | 11034 Object::dynamic_type()); |
| 11287 temp->set_is_final(); | 11035 temp->set_is_final(); |
| 11288 current_block_->scope->AddVariable(temp); | 11036 current_block_->scope->AddVariable(temp); |
| 11289 return temp; | 11037 return temp; |
| 11290 } | 11038 } |
| 11291 | 11039 |
| 11292 | |
| 11293 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, | 11040 AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos, |
| 11294 Token::Kind binary_op, | 11041 Token::Kind binary_op, |
| 11295 AstNode* lhs, | 11042 AstNode* lhs, |
| 11296 AstNode* rhs) { | 11043 AstNode* rhs) { |
| 11297 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 11044 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
| 11298 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 11045 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
| 11299 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 11046 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
| 11300 if (lhs_literal->literal().IsDouble() && | 11047 if (lhs_literal->literal().IsDouble() && |
| 11301 rhs_literal->literal().IsDouble()) { | 11048 rhs_literal->literal().IsDouble()) { |
| 11302 double left_double = Double::Cast(lhs_literal->literal()).value(); | 11049 double left_double = Double::Cast(lhs_literal->literal()).value(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11337 LoadLocalNode* load_left_temp = new (Z) LoadLocalNode(no_pos, left_temp); | 11084 LoadLocalNode* load_left_temp = new (Z) LoadLocalNode(no_pos, left_temp); |
| 11338 ComparisonNode* null_compare = new (Z) | 11085 ComparisonNode* null_compare = new (Z) |
| 11339 ComparisonNode(no_pos, Token::kNE_STRICT, load_left_temp, null_operand); | 11086 ComparisonNode(no_pos, Token::kNE_STRICT, load_left_temp, null_operand); |
| 11340 result->AddNode( | 11087 result->AddNode( |
| 11341 new (Z) ConditionalExprNode(op_pos, null_compare, load_left_temp, rhs)); | 11088 new (Z) ConditionalExprNode(op_pos, null_compare, load_left_temp, rhs)); |
| 11342 return result; | 11089 return result; |
| 11343 } | 11090 } |
| 11344 return new (Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 11091 return new (Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
| 11345 } | 11092 } |
| 11346 | 11093 |
| 11347 | |
| 11348 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, | 11094 AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos, |
| 11349 Token::Kind assignment_op, | 11095 Token::Kind assignment_op, |
| 11350 AstNode* lhs, | 11096 AstNode* lhs, |
| 11351 AstNode* rhs) { | 11097 AstNode* rhs) { |
| 11352 TRACE_PARSER("ExpandAssignableOp"); | 11098 TRACE_PARSER("ExpandAssignableOp"); |
| 11353 switch (assignment_op) { | 11099 switch (assignment_op) { |
| 11354 case Token::kASSIGN: | 11100 case Token::kASSIGN: |
| 11355 return rhs; | 11101 return rhs; |
| 11356 case Token::kASSIGN_ADD: | 11102 case Token::kASSIGN_ADD: |
| 11357 return new (Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 11103 return new (Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 11379 return new (Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); | 11125 return new (Z) BinaryOpNode(op_pos, Token::kIFNULL, lhs, rhs); |
| 11380 default: | 11126 default: |
| 11381 ReportError(op_pos, | 11127 ReportError(op_pos, |
| 11382 "internal error: ExpandAssignableOp '%s' unimplemented", | 11128 "internal error: ExpandAssignableOp '%s' unimplemented", |
| 11383 Token::Name(assignment_op)); | 11129 Token::Name(assignment_op)); |
| 11384 UNIMPLEMENTED(); | 11130 UNIMPLEMENTED(); |
| 11385 return NULL; | 11131 return NULL; |
| 11386 } | 11132 } |
| 11387 } | 11133 } |
| 11388 | 11134 |
| 11389 | |
| 11390 // Evaluates the value of the compile time constant expression | 11135 // Evaluates the value of the compile time constant expression |
| 11391 // and returns a literal node for the value. | 11136 // and returns a literal node for the value. |
| 11392 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { | 11137 LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) { |
| 11393 if (expr->IsLiteralNode()) { | 11138 if (expr->IsLiteralNode()) { |
| 11394 return expr->AsLiteralNode(); | 11139 return expr->AsLiteralNode(); |
| 11395 } | 11140 } |
| 11396 if (expr->EvalConstExpr() == NULL) { | 11141 if (expr->EvalConstExpr() == NULL) { |
| 11397 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 11142 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
| 11398 } | 11143 } |
| 11399 return new (Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); | 11144 return new (Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr)); |
| 11400 } | 11145 } |
| 11401 | 11146 |
| 11402 | |
| 11403 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 11147 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 11404 AstNode* node = *expr; | 11148 AstNode* node = *expr; |
| 11405 TokenPosition token_pos = node->token_pos(); | 11149 TokenPosition token_pos = node->token_pos(); |
| 11406 LetNode* result = new (Z) LetNode(token_pos); | 11150 LetNode* result = new (Z) LetNode(token_pos); |
| 11407 if (node->IsLoadIndexedNode()) { | 11151 if (node->IsLoadIndexedNode()) { |
| 11408 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 11152 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
| 11409 AstNode* array = load_indexed->array(); | 11153 AstNode* array = load_indexed->array(); |
| 11410 AstNode* index = load_indexed->index_expr(); | 11154 AstNode* index = load_indexed->index_expr(); |
| 11411 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 11155 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
| 11412 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 11156 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 11427 LocalVariable* t0 = result->AddInitializer(getter->receiver()); | 11171 LocalVariable* t0 = result->AddInitializer(getter->receiver()); |
| 11428 receiver = new (Z) LoadLocalNode(token_pos, t0); | 11172 receiver = new (Z) LoadLocalNode(token_pos, t0); |
| 11429 } | 11173 } |
| 11430 *expr = new (Z) InstanceGetterNode( | 11174 *expr = new (Z) InstanceGetterNode( |
| 11431 token_pos, receiver, getter->field_name(), getter->is_conditional()); | 11175 token_pos, receiver, getter->field_name(), getter->is_conditional()); |
| 11432 return result; | 11176 return result; |
| 11433 } | 11177 } |
| 11434 return result; | 11178 return result; |
| 11435 } | 11179 } |
| 11436 | 11180 |
| 11437 | |
| 11438 // Check whether the syntax of expression expr is a grammatically legal | 11181 // Check whether the syntax of expression expr is a grammatically legal |
| 11439 // assignable expression. This check is used to detect situations where | 11182 // assignable expression. This check is used to detect situations where |
| 11440 // the expression itself is assignable, but the source is grammatically | 11183 // the expression itself is assignable, but the source is grammatically |
| 11441 // wrong. The AST representation of an expression cannot distinguish | 11184 // wrong. The AST representation of an expression cannot distinguish |
| 11442 // between x = 0 and (x) = 0. The latter is illegal. | 11185 // between x = 0 and (x) = 0. The latter is illegal. |
| 11443 // A syntactically legal assignable expression always ends with an | 11186 // A syntactically legal assignable expression always ends with an |
| 11444 // identifier token or a ] token. We rewind the token iterator and | 11187 // identifier token or a ] token. We rewind the token iterator and |
| 11445 // check whether the token before end_pos is an identifier or ]. | 11188 // check whether the token before end_pos is an identifier or ]. |
| 11446 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos) { | 11189 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos) { |
| 11447 ASSERT(expr->token_pos().IsReal()); | 11190 ASSERT(expr->token_pos().IsReal()); |
| 11448 ASSERT(expr->token_pos() < end_pos); | 11191 ASSERT(expr->token_pos() < end_pos); |
| 11449 SetPosition(expr->token_pos()); | 11192 SetPosition(expr->token_pos()); |
| 11450 Token::Kind token = Token::kILLEGAL; | 11193 Token::Kind token = Token::kILLEGAL; |
| 11451 while (TokenPos() < end_pos) { | 11194 while (TokenPos() < end_pos) { |
| 11452 token = CurrentToken(); | 11195 token = CurrentToken(); |
| 11453 ConsumeToken(); | 11196 ConsumeToken(); |
| 11454 } | 11197 } |
| 11455 ASSERT(TokenPos() == end_pos); | 11198 ASSERT(TokenPos() == end_pos); |
| 11456 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 11199 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
| 11457 } | 11200 } |
| 11458 | 11201 |
| 11459 | |
| 11460 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 11202 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 11461 AstNode* rhs, | 11203 AstNode* rhs, |
| 11462 const String* left_ident, | 11204 const String* left_ident, |
| 11463 TokenPosition left_pos, | 11205 TokenPosition left_pos, |
| 11464 bool is_compound /* = false */) { | 11206 bool is_compound /* = false */) { |
| 11465 AstNode* result = original->MakeAssignmentNode(rhs); | 11207 AstNode* result = original->MakeAssignmentNode(rhs); |
| 11466 if (result == NULL) { | 11208 if (result == NULL) { |
| 11467 String& name = String::ZoneHandle(Z); | 11209 String& name = String::ZoneHandle(Z); |
| 11468 const Class* target_cls = ¤t_class(); | 11210 const Class* target_cls = ¤t_class(); |
| 11469 if (original->IsTypeNode()) { | 11211 if (original->IsTypeNode()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 11500 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { | 11242 (rhs->AsBinaryOpNode()->kind() == Token::kIFNULL)) { |
| 11501 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); | 11243 BinaryOpNode* ifnull = rhs->AsBinaryOpNode(); |
| 11502 AstNode* modified_assign = | 11244 AstNode* modified_assign = |
| 11503 CreateAssignmentNode(original, ifnull->right(), left_ident, left_pos); | 11245 CreateAssignmentNode(original, ifnull->right(), left_ident, left_pos); |
| 11504 result = OptimizeBinaryOpNode(ifnull->token_pos(), ifnull->kind(), | 11246 result = OptimizeBinaryOpNode(ifnull->token_pos(), ifnull->kind(), |
| 11505 ifnull->left(), modified_assign); | 11247 ifnull->left(), modified_assign); |
| 11506 } | 11248 } |
| 11507 return result; | 11249 return result; |
| 11508 } | 11250 } |
| 11509 | 11251 |
| 11510 | |
| 11511 AstNode* Parser::ParseCascades(AstNode* expr) { | 11252 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 11512 TokenPosition cascade_pos = TokenPos(); | 11253 TokenPosition cascade_pos = TokenPos(); |
| 11513 LetNode* cascade = new (Z) LetNode(cascade_pos); | 11254 LetNode* cascade = new (Z) LetNode(cascade_pos); |
| 11514 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 11255 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| 11515 while (CurrentToken() == Token::kCASCADE) { | 11256 while (CurrentToken() == Token::kCASCADE) { |
| 11516 cascade_pos = TokenPos(); | 11257 cascade_pos = TokenPos(); |
| 11517 LoadLocalNode* load_cascade_receiver = | 11258 LoadLocalNode* load_cascade_receiver = |
| 11518 new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var); | 11259 new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
| 11519 if (Token::IsIdentifier(LookaheadToken(1))) { | 11260 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 11520 // Replace .. with . for ParseSelectors(). | 11261 // Replace .. with . for ParseSelectors(). |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11557 } | 11298 } |
| 11558 } | 11299 } |
| 11559 cascade->AddNode(expr); | 11300 cascade->AddNode(expr); |
| 11560 } | 11301 } |
| 11561 // The result is an expression with the (side effects of the) cascade | 11302 // The result is an expression with the (side effects of the) cascade |
| 11562 // sequence followed by the (value of the) receiver temp variable load. | 11303 // sequence followed by the (value of the) receiver temp variable load. |
| 11563 cascade->AddNode(new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); | 11304 cascade->AddNode(new (Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); |
| 11564 return cascade; | 11305 return cascade; |
| 11565 } | 11306 } |
| 11566 | 11307 |
| 11567 | |
| 11568 // Convert loading of a static const field into a literal node. | 11308 // Convert loading of a static const field into a literal node. |
| 11569 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { | 11309 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { |
| 11570 if (expr->IsLoadStaticFieldNode()) { | 11310 if (expr->IsLoadStaticFieldNode()) { |
| 11571 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 11311 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 11572 if (field.is_const() && | 11312 if (field.is_const() && |
| 11573 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { | 11313 !expr->AsLoadStaticFieldNode()->is_deferred_reference()) { |
| 11574 ASSERT(field.StaticValue() != Object::sentinel().raw()); | 11314 ASSERT(field.StaticValue() != Object::sentinel().raw()); |
| 11575 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); | 11315 ASSERT(field.StaticValue() != Object::transition_sentinel().raw()); |
| 11576 return new (zone) LiteralNode( | 11316 return new (zone) LiteralNode( |
| 11577 expr->token_pos(), Instance::ZoneHandle(zone, field.StaticValue())); | 11317 expr->token_pos(), Instance::ZoneHandle(zone, field.StaticValue())); |
| 11578 } | 11318 } |
| 11579 } | 11319 } |
| 11580 return expr; | 11320 return expr; |
| 11581 } | 11321 } |
| 11582 | 11322 |
| 11583 | |
| 11584 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, | 11323 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
| 11585 bool consume_cascades, | 11324 bool consume_cascades, |
| 11586 SequenceNode** await_preamble) { | 11325 SequenceNode** await_preamble) { |
| 11587 TRACE_PARSER("ParseAwaitableExpr"); | 11326 TRACE_PARSER("ParseAwaitableExpr"); |
| 11588 BoolScope saved_seen_await(&parsed_function()->have_seen_await_expr_, false); | 11327 BoolScope saved_seen_await(&parsed_function()->have_seen_await_expr_, false); |
| 11589 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 11328 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 11590 if (parsed_function()->have_seen_await()) { | 11329 if (parsed_function()->have_seen_await()) { |
| 11591 // Make sure we do not reuse the scope to avoid creating contexts that we | 11330 // Make sure we do not reuse the scope to avoid creating contexts that we |
| 11592 // are unaware of, i.e, creating contexts that have already been covered. | 11331 // are unaware of, i.e, creating contexts that have already been covered. |
| 11593 // See FlowGraphBuilder::VisitSequenceNode() for details on when contexts | 11332 // See FlowGraphBuilder::VisitSequenceNode() for details on when contexts |
| 11594 // are created. | 11333 // are created. |
| 11595 OpenBlock(); | 11334 OpenBlock(); |
| 11596 AwaitTransformer at(current_block_->statements, async_temp_scope_); | 11335 AwaitTransformer at(current_block_->statements, async_temp_scope_); |
| 11597 AstNode* result = at.Transform(expr); | 11336 AstNode* result = at.Transform(expr); |
| 11598 SequenceNode* preamble = CloseBlock(); | 11337 SequenceNode* preamble = CloseBlock(); |
| 11599 if (await_preamble == NULL) { | 11338 if (await_preamble == NULL) { |
| 11600 current_block_->statements->Add(preamble); | 11339 current_block_->statements->Add(preamble); |
| 11601 } else { | 11340 } else { |
| 11602 *await_preamble = preamble; | 11341 *await_preamble = preamble; |
| 11603 } | 11342 } |
| 11604 return result; | 11343 return result; |
| 11605 } | 11344 } |
| 11606 return expr; | 11345 return expr; |
| 11607 } | 11346 } |
| 11608 | 11347 |
| 11609 | |
| 11610 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 11348 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 11611 bool consume_cascades) { | 11349 bool consume_cascades) { |
| 11612 TRACE_PARSER("ParseExpr"); | 11350 TRACE_PARSER("ParseExpr"); |
| 11613 String* expr_ident = | 11351 String* expr_ident = |
| 11614 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11352 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 11615 const TokenPosition expr_pos = TokenPos(); | 11353 const TokenPosition expr_pos = TokenPos(); |
| 11616 | 11354 |
| 11617 RecursionChecker rc(this); | 11355 RecursionChecker rc(this); |
| 11618 | 11356 |
| 11619 if (CurrentToken() == Token::kTHROW) { | 11357 if (CurrentToken() == Token::kTHROW) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11674 return let_expr; | 11412 return let_expr; |
| 11675 } else { | 11413 } else { |
| 11676 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 11414 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
| 11677 AstNode* assign_expr = | 11415 AstNode* assign_expr = |
| 11678 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 11416 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 11679 ASSERT(assign_expr != NULL); | 11417 ASSERT(assign_expr != NULL); |
| 11680 return assign_expr; | 11418 return assign_expr; |
| 11681 } | 11419 } |
| 11682 } | 11420 } |
| 11683 | 11421 |
| 11684 | |
| 11685 LiteralNode* Parser::ParseConstExpr() { | 11422 LiteralNode* Parser::ParseConstExpr() { |
| 11686 TRACE_PARSER("ParseConstExpr"); | 11423 TRACE_PARSER("ParseConstExpr"); |
| 11687 TokenPosition expr_pos = TokenPos(); | 11424 TokenPosition expr_pos = TokenPos(); |
| 11688 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 11425 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| 11689 if (!expr->IsLiteralNode()) { | 11426 if (!expr->IsLiteralNode()) { |
| 11690 ReportError(expr_pos, "expression must be a compile-time constant"); | 11427 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 11691 } | 11428 } |
| 11692 return expr->AsLiteralNode(); | 11429 return expr->AsLiteralNode(); |
| 11693 } | 11430 } |
| 11694 | 11431 |
| 11695 | |
| 11696 AstNode* Parser::ParseConditionalExpr() { | 11432 AstNode* Parser::ParseConditionalExpr() { |
| 11697 TRACE_PARSER("ParseConditionalExpr"); | 11433 TRACE_PARSER("ParseConditionalExpr"); |
| 11698 const TokenPosition expr_pos = TokenPos(); | 11434 const TokenPosition expr_pos = TokenPos(); |
| 11699 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); | 11435 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
| 11700 if (CurrentToken() == Token::kCONDITIONAL) { | 11436 if (CurrentToken() == Token::kCONDITIONAL) { |
| 11701 EnsureExpressionTemp(); | 11437 EnsureExpressionTemp(); |
| 11702 ConsumeToken(); | 11438 ConsumeToken(); |
| 11703 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 11439 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
| 11704 ExpectToken(Token::kCOLON); | 11440 ExpectToken(Token::kCOLON); |
| 11705 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 11441 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
| 11706 expr = new (Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 11442 expr = new (Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 11707 } | 11443 } |
| 11708 return expr; | 11444 return expr; |
| 11709 } | 11445 } |
| 11710 | 11446 |
| 11711 | |
| 11712 AstNode* Parser::ParseUnaryExpr() { | 11447 AstNode* Parser::ParseUnaryExpr() { |
| 11713 TRACE_PARSER("ParseUnaryExpr"); | 11448 TRACE_PARSER("ParseUnaryExpr"); |
| 11714 AstNode* expr = NULL; | 11449 AstNode* expr = NULL; |
| 11715 const TokenPosition op_pos = TokenPos(); | 11450 const TokenPosition op_pos = TokenPos(); |
| 11716 if (IsAwaitKeyword()) { | 11451 if (IsAwaitKeyword()) { |
| 11717 TRACE_PARSER("ParseAwaitExpr"); | 11452 TRACE_PARSER("ParseAwaitExpr"); |
| 11718 if (!innermost_function().IsAsyncFunction() && | 11453 if (!innermost_function().IsAsyncFunction() && |
| 11719 !innermost_function().IsAsyncClosure() && | 11454 !innermost_function().IsAsyncClosure() && |
| 11720 !innermost_function().IsAsyncGenerator() && | 11455 !innermost_function().IsAsyncGenerator() && |
| 11721 !innermost_function().IsAsyncGenClosure()) { | 11456 !innermost_function().IsAsyncGenClosure()) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11766 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); | 11501 CreateAssignmentNode(expr, add, expr_ident, expr_pos, true); |
| 11767 ASSERT(store != NULL); | 11502 ASSERT(store != NULL); |
| 11768 let_expr->AddNode(store); | 11503 let_expr->AddNode(store); |
| 11769 expr = let_expr; | 11504 expr = let_expr; |
| 11770 } else { | 11505 } else { |
| 11771 expr = ParsePostfixExpr(); | 11506 expr = ParsePostfixExpr(); |
| 11772 } | 11507 } |
| 11773 return expr; | 11508 return expr; |
| 11774 } | 11509 } |
| 11775 | 11510 |
| 11776 | |
| 11777 ArgumentListNode* Parser::ParseActualParameters( | 11511 ArgumentListNode* Parser::ParseActualParameters( |
| 11778 ArgumentListNode* implicit_arguments, | 11512 ArgumentListNode* implicit_arguments, |
| 11779 const TypeArguments& func_type_args, | 11513 const TypeArguments& func_type_args, |
| 11780 bool require_const) { | 11514 bool require_const) { |
| 11781 TRACE_PARSER("ParseActualParameters"); | 11515 TRACE_PARSER("ParseActualParameters"); |
| 11782 ASSERT(CurrentToken() == Token::kLPAREN); | 11516 ASSERT(CurrentToken() == Token::kLPAREN); |
| 11783 const bool saved_mode = SetAllowFunctionLiterals(true); | 11517 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 11784 ArgumentListNode* arguments; | 11518 ArgumentListNode* arguments; |
| 11785 if (implicit_arguments == NULL) { | 11519 if (implicit_arguments == NULL) { |
| 11786 // TODO(regis): When require_const is true, do we need to check that | 11520 // TODO(regis): When require_const is true, do we need to check that |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11828 ConsumeToken(); | 11562 ConsumeToken(); |
| 11829 } | 11563 } |
| 11830 ExpectToken(Token::kRPAREN); | 11564 ExpectToken(Token::kRPAREN); |
| 11831 SetAllowFunctionLiterals(saved_mode); | 11565 SetAllowFunctionLiterals(saved_mode); |
| 11832 if (named_argument_seen) { | 11566 if (named_argument_seen) { |
| 11833 arguments->set_names(Array::Handle(Z, Array::MakeFixedLength(names))); | 11567 arguments->set_names(Array::Handle(Z, Array::MakeFixedLength(names))); |
| 11834 } | 11568 } |
| 11835 return arguments; | 11569 return arguments; |
| 11836 } | 11570 } |
| 11837 | 11571 |
| 11838 | |
| 11839 AstNode* Parser::ParseStaticCall(const Class& cls, | 11572 AstNode* Parser::ParseStaticCall(const Class& cls, |
| 11840 const String& func_name, | 11573 const String& func_name, |
| 11841 TokenPosition ident_pos, | 11574 TokenPosition ident_pos, |
| 11842 const TypeArguments& func_type_args, | 11575 const TypeArguments& func_type_args, |
| 11843 const LibraryPrefix* prefix) { | 11576 const LibraryPrefix* prefix) { |
| 11844 TRACE_PARSER("ParseStaticCall"); | 11577 TRACE_PARSER("ParseStaticCall"); |
| 11845 const TokenPosition call_pos = TokenPos(); | 11578 const TokenPosition call_pos = TokenPos(); |
| 11846 ASSERT(CurrentToken() == Token::kLPAREN); | 11579 ASSERT(CurrentToken() == Token::kLPAREN); |
| 11847 ArgumentListNode* arguments = | 11580 ArgumentListNode* arguments = |
| 11848 ParseActualParameters(NULL, func_type_args, kAllowConst); | 11581 ParseActualParameters(NULL, func_type_args, kAllowConst); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11907 1, new (Z) LiteralNode(arg1->token_pos(), | 11640 1, new (Z) LiteralNode(arg1->token_pos(), |
| 11908 EvaluateConstExpr(arg1->token_pos(), arg1))); | 11641 EvaluateConstExpr(arg1->token_pos(), arg1))); |
| 11909 } | 11642 } |
| 11910 } | 11643 } |
| 11911 return new (Z) ComparisonNode(ident_pos, Token::kEQ_STRICT, | 11644 return new (Z) ComparisonNode(ident_pos, Token::kEQ_STRICT, |
| 11912 arguments->NodeAt(0), arguments->NodeAt(1)); | 11645 arguments->NodeAt(0), arguments->NodeAt(1)); |
| 11913 } | 11646 } |
| 11914 return new (Z) StaticCallNode(ident_pos, func, arguments); | 11647 return new (Z) StaticCallNode(ident_pos, func, arguments); |
| 11915 } | 11648 } |
| 11916 | 11649 |
| 11917 | |
| 11918 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 11650 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
| 11919 const String& func_name, | 11651 const String& func_name, |
| 11920 TokenPosition ident_pos, | 11652 TokenPosition ident_pos, |
| 11921 const TypeArguments& func_type_args, | 11653 const TypeArguments& func_type_args, |
| 11922 bool is_conditional) { | 11654 bool is_conditional) { |
| 11923 TRACE_PARSER("ParseInstanceCall"); | 11655 TRACE_PARSER("ParseInstanceCall"); |
| 11924 CheckToken(Token::kLPAREN); | 11656 CheckToken(Token::kLPAREN); |
| 11925 ArgumentListNode* arguments = | 11657 ArgumentListNode* arguments = |
| 11926 ParseActualParameters(NULL, func_type_args, kAllowConst); | 11658 ParseActualParameters(NULL, func_type_args, kAllowConst); |
| 11927 return new (Z) InstanceCallNode(ident_pos, receiver, func_name, arguments, | 11659 return new (Z) InstanceCallNode(ident_pos, receiver, func_name, arguments, |
| 11928 is_conditional); | 11660 is_conditional); |
| 11929 } | 11661 } |
| 11930 | 11662 |
| 11931 | |
| 11932 AstNode* Parser::ParseClosureCall(AstNode* closure, | 11663 AstNode* Parser::ParseClosureCall(AstNode* closure, |
| 11933 const TypeArguments& func_type_args) { | 11664 const TypeArguments& func_type_args) { |
| 11934 TRACE_PARSER("ParseClosureCall"); | 11665 TRACE_PARSER("ParseClosureCall"); |
| 11935 const TokenPosition call_pos = TokenPos(); | 11666 const TokenPosition call_pos = TokenPos(); |
| 11936 ASSERT(CurrentToken() == Token::kLPAREN); | 11667 ASSERT(CurrentToken() == Token::kLPAREN); |
| 11937 ArgumentListNode* arguments = | 11668 ArgumentListNode* arguments = |
| 11938 ParseActualParameters(NULL, func_type_args, kAllowConst); | 11669 ParseActualParameters(NULL, func_type_args, kAllowConst); |
| 11939 return BuildClosureCall(call_pos, closure, arguments); | 11670 return BuildClosureCall(call_pos, closure, arguments); |
| 11940 } | 11671 } |
| 11941 | 11672 |
| 11942 | |
| 11943 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 11673 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 11944 TokenPosition ident_pos) { | 11674 TokenPosition ident_pos) { |
| 11945 // If the static field has an initializer, initialize the field at compile | 11675 // If the static field has an initializer, initialize the field at compile |
| 11946 // time, which is only possible if the field is const. | 11676 // time, which is only possible if the field is const. |
| 11947 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11677 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
| 11948 if (initializing_getter != NULL) { | 11678 if (initializing_getter != NULL) { |
| 11949 // The field is not yet initialized and could not be initialized at compile | 11679 // The field is not yet initialized and could not be initialized at compile |
| 11950 // time. The getter will initialize the field. | 11680 // time. The getter will initialize the field. |
| 11951 return initializing_getter; | 11681 return initializing_getter; |
| 11952 } | 11682 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 11963 return new (Z) | 11693 return new (Z) |
| 11964 LoadStaticFieldNode(ident_pos, Field::ZoneHandle(Z, field.raw())); | 11694 LoadStaticFieldNode(ident_pos, Field::ZoneHandle(Z, field.raw())); |
| 11965 } else { | 11695 } else { |
| 11966 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); | 11696 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 11967 return new (Z) StaticGetterNode(ident_pos, | 11697 return new (Z) StaticGetterNode(ident_pos, |
| 11968 NULL, // Receiver. | 11698 NULL, // Receiver. |
| 11969 field_owner, field_name); | 11699 field_owner, field_name); |
| 11970 } | 11700 } |
| 11971 } | 11701 } |
| 11972 | 11702 |
| 11973 | |
| 11974 // Reference to 'field_name' with explicit class as primary. | 11703 // Reference to 'field_name' with explicit class as primary. |
| 11975 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, | 11704 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, |
| 11976 const String& field_name, | 11705 const String& field_name, |
| 11977 TokenPosition ident_pos) { | 11706 TokenPosition ident_pos) { |
| 11978 AstNode* access = NULL; | 11707 AstNode* access = NULL; |
| 11979 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); | 11708 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
| 11980 Function& func = Function::ZoneHandle(Z); | 11709 Function& func = Function::ZoneHandle(Z); |
| 11981 if (field.IsNull()) { | 11710 if (field.IsNull()) { |
| 11982 // No field, check if we have an explicit getter function. | 11711 // No field, check if we have an explicit getter function. |
| 11983 func = cls.LookupGetterFunction(field_name); | 11712 func = cls.LookupGetterFunction(field_name); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 12000 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 11729 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 12001 access = new (Z) StaticGetterNode( | 11730 access = new (Z) StaticGetterNode( |
| 12002 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); | 11731 ident_pos, NULL, Class::ZoneHandle(Z, cls.raw()), field_name); |
| 12003 } | 11732 } |
| 12004 } else { | 11733 } else { |
| 12005 access = GenerateStaticFieldLookup(field, ident_pos); | 11734 access = GenerateStaticFieldLookup(field, ident_pos); |
| 12006 } | 11735 } |
| 12007 return access; | 11736 return access; |
| 12008 } | 11737 } |
| 12009 | 11738 |
| 12010 | |
| 12011 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 11739 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
| 12012 if (!node->IsPrimaryNode()) { | 11740 if (!node->IsPrimaryNode()) { |
| 12013 return node; | 11741 return node; |
| 12014 } | 11742 } |
| 12015 PrimaryNode* primary = node->AsPrimaryNode(); | 11743 PrimaryNode* primary = node->AsPrimaryNode(); |
| 12016 if (primary->primary().IsString()) { | 11744 if (primary->primary().IsString()) { |
| 12017 if (primary->IsSuper()) { | 11745 if (primary->IsSuper()) { |
| 12018 return primary; | 11746 return primary; |
| 12019 } | 11747 } |
| 12020 // In a static method, evaluation of an unresolved identifier causes a | 11748 // In a static method, evaluation of an unresolved identifier causes a |
| (...skipping 18 matching lines...) Expand all Loading... |
| 12039 getter->set_is_deferred(primary->is_deferred_reference()); | 11767 getter->set_is_deferred(primary->is_deferred_reference()); |
| 12040 return getter; | 11768 return getter; |
| 12041 } else { | 11769 } else { |
| 12042 AstNode* receiver = LoadReceiver(primary->token_pos()); | 11770 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 12043 return CallGetter(node->token_pos(), receiver, name); | 11771 return CallGetter(node->token_pos(), receiver, name); |
| 12044 } | 11772 } |
| 12045 } | 11773 } |
| 12046 return primary; | 11774 return primary; |
| 12047 } | 11775 } |
| 12048 | 11776 |
| 12049 | |
| 12050 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 11777 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
| 12051 ASSERT(primary->primary().IsFunction()); | 11778 ASSERT(primary->primary().IsFunction()); |
| 12052 const Function& func = | 11779 const Function& func = |
| 12053 Function::Cast(Object::ZoneHandle(primary->primary().raw())); | 11780 Function::Cast(Object::ZoneHandle(primary->primary().raw())); |
| 12054 const String& funcname = String::ZoneHandle(Z, func.name()); | 11781 const String& funcname = String::ZoneHandle(Z, func.name()); |
| 12055 if (func.is_static()) { | 11782 if (func.is_static()) { |
| 12056 // Static function access. | 11783 // Static function access. |
| 12057 ClosureNode* closure = | 11784 ClosureNode* closure = |
| 12058 CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 11785 CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
| 12059 closure->set_is_deferred(primary->is_deferred_reference()); | 11786 closure->set_is_deferred(primary->is_deferred_reference()); |
| 12060 return closure; | 11787 return closure; |
| 12061 } else { | 11788 } else { |
| 12062 // Instance function access. | 11789 // Instance function access. |
| 12063 if (current_function().is_static() || | 11790 if (current_function().is_static() || |
| 12064 current_function().IsInFactoryScope()) { | 11791 current_function().IsInFactoryScope()) { |
| 12065 ReportError(primary->token_pos(), | 11792 ReportError(primary->token_pos(), |
| 12066 "cannot access instance method '%s' from static method", | 11793 "cannot access instance method '%s' from static method", |
| 12067 funcname.ToCString()); | 11794 funcname.ToCString()); |
| 12068 } | 11795 } |
| 12069 AstNode* receiver = LoadReceiver(primary->token_pos()); | 11796 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 12070 return CallGetter(primary->token_pos(), receiver, funcname); | 11797 return CallGetter(primary->token_pos(), receiver, funcname); |
| 12071 } | 11798 } |
| 12072 UNREACHABLE(); | 11799 UNREACHABLE(); |
| 12073 return NULL; | 11800 return NULL; |
| 12074 } | 11801 } |
| 12075 | 11802 |
| 12076 | |
| 12077 AstNode* Parser::LoadTypeParameter(PrimaryNode* primary) { | 11803 AstNode* Parser::LoadTypeParameter(PrimaryNode* primary) { |
| 12078 const TokenPosition primary_pos = primary->token_pos(); | 11804 const TokenPosition primary_pos = primary->token_pos(); |
| 12079 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11805 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
| 12080 type_parameter = TypeParameter::Cast(primary->primary()).raw(); | 11806 type_parameter = TypeParameter::Cast(primary->primary()).raw(); |
| 12081 if (type_parameter.IsClassTypeParameter()) { | 11807 if (type_parameter.IsClassTypeParameter()) { |
| 12082 if (ParsingStaticMember()) { | 11808 if (ParsingStaticMember()) { |
| 12083 const String& name = String::Handle(Z, type_parameter.name()); | 11809 const String& name = String::Handle(Z, type_parameter.name()); |
| 12084 ReportError(primary_pos, | 11810 ReportError(primary_pos, |
| 12085 "cannot access type parameter '%s' " | 11811 "cannot access type parameter '%s' " |
| 12086 "from static function", | 11812 "from static function", |
| (...skipping 13 matching lines...) Expand all Loading... |
| 12100 if (FunctionLevel() > 0) { | 11826 if (FunctionLevel() > 0) { |
| 12101 // Make sure that the parent function type arguments are captured. | 11827 // Make sure that the parent function type arguments are captured. |
| 12102 CaptureFunctionTypeArguments(); | 11828 CaptureFunctionTypeArguments(); |
| 12103 } | 11829 } |
| 12104 } | 11830 } |
| 12105 ASSERT(type_parameter.IsFinalized()); | 11831 ASSERT(type_parameter.IsFinalized()); |
| 12106 ASSERT(!type_parameter.IsMalformed()); | 11832 ASSERT(!type_parameter.IsMalformed()); |
| 12107 return new (Z) TypeNode(primary_pos, type_parameter); | 11833 return new (Z) TypeNode(primary_pos, type_parameter); |
| 12108 } | 11834 } |
| 12109 | 11835 |
| 12110 | |
| 12111 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 11836 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
| 12112 AstNode* left = primary; | 11837 AstNode* left = primary; |
| 12113 while (true) { | 11838 while (true) { |
| 12114 AstNode* selector = NULL; | 11839 AstNode* selector = NULL; |
| 12115 if ((CurrentToken() == Token::kPERIOD) || | 11840 if ((CurrentToken() == Token::kPERIOD) || |
| 12116 (CurrentToken() == Token::kQM_PERIOD)) { | 11841 (CurrentToken() == Token::kQM_PERIOD)) { |
| 12117 // Unconditional or conditional property extraction or method call. | 11842 // Unconditional or conditional property extraction or method call. |
| 12118 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | 11843 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; |
| 12119 ConsumeToken(); | 11844 ConsumeToken(); |
| 12120 if (left->IsPrimaryNode()) { | 11845 if (left->IsPrimaryNode()) { |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12348 } | 12073 } |
| 12349 } | 12074 } |
| 12350 // Done parsing selectors. | 12075 // Done parsing selectors. |
| 12351 return left; | 12076 return left; |
| 12352 } | 12077 } |
| 12353 ASSERT(selector != NULL); | 12078 ASSERT(selector != NULL); |
| 12354 left = selector; | 12079 left = selector; |
| 12355 } | 12080 } |
| 12356 } | 12081 } |
| 12357 | 12082 |
| 12358 | |
| 12359 // Closurization e#m of getter, setter, method or operator. | 12083 // Closurization e#m of getter, setter, method or operator. |
| 12360 AstNode* Parser::ParseClosurization(AstNode* primary) { | 12084 AstNode* Parser::ParseClosurization(AstNode* primary) { |
| 12361 if (!FLAG_support_deprecated_tearoff_syntax) { | 12085 if (!FLAG_support_deprecated_tearoff_syntax) { |
| 12362 ReportError("tear-off using the x#id syntax is a deprecated feature"); | 12086 ReportError("tear-off using the x#id syntax is a deprecated feature"); |
| 12363 return NULL; | 12087 return NULL; |
| 12364 } | 12088 } |
| 12365 ExpectToken(Token::kHASH); | 12089 ExpectToken(Token::kHASH); |
| 12366 TokenPosition property_pos = TokenPos(); | 12090 TokenPosition property_pos = TokenPos(); |
| 12367 bool is_setter_name = false; | 12091 bool is_setter_name = false; |
| 12368 | 12092 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12504 GrowableHandlePtrArray<const String> pieces(Z, 3); | 12228 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 12505 pieces.Add(Symbols::HashMark()); | 12229 pieces.Add(Symbols::HashMark()); |
| 12506 if (is_setter_name) { | 12230 if (is_setter_name) { |
| 12507 pieces.Add(Symbols::SetterPrefix()); | 12231 pieces.Add(Symbols::SetterPrefix()); |
| 12508 } | 12232 } |
| 12509 pieces.Add(extractor_name); | 12233 pieces.Add(extractor_name); |
| 12510 extractor_name = Symbols::FromConcatAll(T, pieces); | 12234 extractor_name = Symbols::FromConcatAll(T, pieces); |
| 12511 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); | 12235 return new (Z) InstanceGetterNode(property_pos, primary, extractor_name); |
| 12512 } | 12236 } |
| 12513 | 12237 |
| 12514 | |
| 12515 AstNode* Parser::ParsePostfixExpr() { | 12238 AstNode* Parser::ParsePostfixExpr() { |
| 12516 TRACE_PARSER("ParsePostfixExpr"); | 12239 TRACE_PARSER("ParsePostfixExpr"); |
| 12517 String* expr_ident = | 12240 String* expr_ident = |
| 12518 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 12241 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 12519 const TokenPosition expr_pos = TokenPos(); | 12242 const TokenPosition expr_pos = TokenPos(); |
| 12520 AstNode* expr = ParsePrimary(); | 12243 AstNode* expr = ParsePrimary(); |
| 12521 if (CurrentToken() == Token::kHASH) { | 12244 if (CurrentToken() == Token::kHASH) { |
| 12522 expr = LoadFieldIfUnresolved(expr); | 12245 expr = LoadFieldIfUnresolved(expr); |
| 12523 expr = ParseClosurization(expr); | 12246 expr = ParseClosurization(expr); |
| 12524 } else { | 12247 } else { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 12545 ASSERT(store != NULL); | 12268 ASSERT(store != NULL); |
| 12546 // The result is a pair of the (side effects of the) store followed by | 12269 // The result is a pair of the (side effects of the) store followed by |
| 12547 // the (value of the) initial value temp variable load. | 12270 // the (value of the) initial value temp variable load. |
| 12548 let_expr->AddNode(store); | 12271 let_expr->AddNode(store); |
| 12549 let_expr->AddNode(new (Z) LoadLocalNode(op_pos, temp)); | 12272 let_expr->AddNode(new (Z) LoadLocalNode(op_pos, temp)); |
| 12550 return let_expr; | 12273 return let_expr; |
| 12551 } | 12274 } |
| 12552 return expr; | 12275 return expr; |
| 12553 } | 12276 } |
| 12554 | 12277 |
| 12555 | |
| 12556 // Resolve the type parameters that may appear in the given signature from the | 12278 // Resolve the type parameters that may appear in the given signature from the |
| 12557 // signature function and current class. | 12279 // signature function and current class. |
| 12558 // Unresolved type classes get resolved later by the class finalizer. | 12280 // Unresolved type classes get resolved later by the class finalizer. |
| 12559 void Parser::ResolveSignature(const Function& signature) { | 12281 void Parser::ResolveSignature(const Function& signature) { |
| 12560 const Function& saved_innermost_function = | 12282 const Function& saved_innermost_function = |
| 12561 Function::Handle(Z, innermost_function().raw()); | 12283 Function::Handle(Z, innermost_function().raw()); |
| 12562 innermost_function_ = signature.raw(); | 12284 innermost_function_ = signature.raw(); |
| 12563 AbstractType& type = AbstractType::Handle(); | 12285 AbstractType& type = AbstractType::Handle(); |
| 12564 // Resolve upper bounds of function type parameters. | 12286 // Resolve upper bounds of function type parameters. |
| 12565 const intptr_t num_type_params = signature.NumTypeParameters(); | 12287 const intptr_t num_type_params = signature.NumTypeParameters(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 12581 // Resolve formal parameter types. | 12303 // Resolve formal parameter types. |
| 12582 const intptr_t num_parameters = signature.NumParameters(); | 12304 const intptr_t num_parameters = signature.NumParameters(); |
| 12583 for (intptr_t i = 0; i < num_parameters; i++) { | 12305 for (intptr_t i = 0; i < num_parameters; i++) { |
| 12584 type = signature.ParameterTypeAt(i); | 12306 type = signature.ParameterTypeAt(i); |
| 12585 ResolveType(&type); | 12307 ResolveType(&type); |
| 12586 signature.SetParameterTypeAt(i, type); | 12308 signature.SetParameterTypeAt(i, type); |
| 12587 } | 12309 } |
| 12588 innermost_function_ = saved_innermost_function.raw(); | 12310 innermost_function_ = saved_innermost_function.raw(); |
| 12589 } | 12311 } |
| 12590 | 12312 |
| 12591 | |
| 12592 // Resolve the type parameters that may appear in the given type and in its type | 12313 // Resolve the type parameters that may appear in the given type and in its type |
| 12593 // arguments from the current function and current class. | 12314 // arguments from the current function and current class. |
| 12594 // Unresolved type classes get resolved later by the class finalizer. | 12315 // Unresolved type classes get resolved later by the class finalizer. |
| 12595 void Parser::ResolveType(AbstractType* type) { | 12316 void Parser::ResolveType(AbstractType* type) { |
| 12596 ASSERT(type != NULL); | 12317 ASSERT(type != NULL); |
| 12597 if (type->IsResolved()) { | 12318 if (type->IsResolved()) { |
| 12598 // Some types are resolved by definition, such as a TypeParameter. | 12319 // Some types are resolved by definition, such as a TypeParameter. |
| 12599 return; | 12320 return; |
| 12600 } | 12321 } |
| 12601 // Resolve type class. | 12322 // Resolve type class. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12681 Function::Handle(Z, Type::Cast(*type).signature()); | 12402 Function::Handle(Z, Type::Cast(*type).signature()); |
| 12682 Type& signature_type = Type::Handle(Z, signature.SignatureType()); | 12403 Type& signature_type = Type::Handle(Z, signature.SignatureType()); |
| 12683 if (signature_type.raw() != type->raw()) { | 12404 if (signature_type.raw() != type->raw()) { |
| 12684 ResolveType(&signature_type); | 12405 ResolveType(&signature_type); |
| 12685 } else { | 12406 } else { |
| 12686 ResolveSignature(signature); | 12407 ResolveSignature(signature); |
| 12687 } | 12408 } |
| 12688 } | 12409 } |
| 12689 } | 12410 } |
| 12690 | 12411 |
| 12691 | |
| 12692 RawAbstractType* Parser::CanonicalizeType(const AbstractType& type) { | 12412 RawAbstractType* Parser::CanonicalizeType(const AbstractType& type) { |
| 12693 // If the current class is the result of a mixin application, we must | 12413 // If the current class is the result of a mixin application, we must |
| 12694 // use the class scope of the class from which the function originates. | 12414 // use the class scope of the class from which the function originates. |
| 12695 if (current_class().IsMixinApplication()) { | 12415 if (current_class().IsMixinApplication()) { |
| 12696 return ClassFinalizer::FinalizeType( | 12416 return ClassFinalizer::FinalizeType( |
| 12697 Class::Handle(Z, parsed_function()->function().origin()), type); | 12417 Class::Handle(Z, parsed_function()->function().origin()), type); |
| 12698 } | 12418 } |
| 12699 return ClassFinalizer::FinalizeType(current_class(), type); | 12419 return ClassFinalizer::FinalizeType(current_class(), type); |
| 12700 } | 12420 } |
| 12701 | 12421 |
| 12702 | |
| 12703 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 12422 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 12704 if (current_block_ == NULL) { | 12423 if (current_block_ == NULL) { |
| 12705 return NULL; | 12424 return NULL; |
| 12706 } | 12425 } |
| 12707 // A found name is treated as accessed and possibly marked as captured. | 12426 // A found name is treated as accessed and possibly marked as captured. |
| 12708 const bool kTestOnly = false; | 12427 const bool kTestOnly = false; |
| 12709 return current_block_->scope->LookupVariable(ident, kTestOnly); | 12428 return current_block_->scope->LookupVariable(ident, kTestOnly); |
| 12710 } | 12429 } |
| 12711 | 12430 |
| 12712 | |
| 12713 void Parser::CheckInstanceFieldAccess(TokenPosition field_pos, | 12431 void Parser::CheckInstanceFieldAccess(TokenPosition field_pos, |
| 12714 const String& field_name) { | 12432 const String& field_name) { |
| 12715 // Fields are not accessible from a static function, except from a | 12433 // Fields are not accessible from a static function, except from a |
| 12716 // constructor, which is considered as non-static by the compiler. | 12434 // constructor, which is considered as non-static by the compiler. |
| 12717 if (current_function().is_static()) { | 12435 if (current_function().is_static()) { |
| 12718 ReportError(field_pos, | 12436 ReportError(field_pos, |
| 12719 "cannot access instance field '%s' from a static function", | 12437 "cannot access instance field '%s' from a static function", |
| 12720 field_name.ToCString()); | 12438 field_name.ToCString()); |
| 12721 } | 12439 } |
| 12722 } | 12440 } |
| 12723 | 12441 |
| 12724 | |
| 12725 bool Parser::ParsingStaticMember() const { | 12442 bool Parser::ParsingStaticMember() const { |
| 12726 if (is_top_level_) { | 12443 if (is_top_level_) { |
| 12727 return (current_member_ != NULL) && current_member_->has_static && | 12444 return (current_member_ != NULL) && current_member_->has_static && |
| 12728 !current_member_->has_factory; | 12445 !current_member_->has_factory; |
| 12729 } | 12446 } |
| 12730 ASSERT(!current_function().IsNull()); | 12447 ASSERT(!current_function().IsNull()); |
| 12731 return current_function().is_static() && | 12448 return current_function().is_static() && |
| 12732 !current_function().IsInFactoryScope(); | 12449 !current_function().IsInFactoryScope(); |
| 12733 } | 12450 } |
| 12734 | 12451 |
| 12735 | |
| 12736 const AbstractType* Parser::ReceiverType(const Class& cls) { | 12452 const AbstractType* Parser::ReceiverType(const Class& cls) { |
| 12737 ASSERT(!cls.IsNull()); | 12453 ASSERT(!cls.IsNull()); |
| 12738 ASSERT(!cls.IsTypedefClass()); | 12454 ASSERT(!cls.IsTypedefClass()); |
| 12739 // Note that if cls is _Closure, the returned type will be _Closure, | 12455 // Note that if cls is _Closure, the returned type will be _Closure, |
| 12740 // and not the signature type. | 12456 // and not the signature type. |
| 12741 Type& type = Type::ZoneHandle(Z, cls.CanonicalType()); | 12457 Type& type = Type::ZoneHandle(Z, cls.CanonicalType()); |
| 12742 if (!type.IsNull()) { | 12458 if (!type.IsNull()) { |
| 12743 return &type; | 12459 return &type; |
| 12744 } | 12460 } |
| 12745 type = Type::New(cls, TypeArguments::Handle(Z, cls.type_parameters()), | 12461 type = Type::New(cls, TypeArguments::Handle(Z, cls.type_parameters()), |
| 12746 cls.token_pos(), Heap::kOld); | 12462 cls.token_pos(), Heap::kOld); |
| 12747 if (cls.is_type_finalized()) { | 12463 if (cls.is_type_finalized()) { |
| 12748 type ^= ClassFinalizer::FinalizeType(cls, type); | 12464 type ^= ClassFinalizer::FinalizeType(cls, type); |
| 12749 // Note that the receiver type may now be a malbounded type. | 12465 // Note that the receiver type may now be a malbounded type. |
| 12750 cls.SetCanonicalType(type); | 12466 cls.SetCanonicalType(type); |
| 12751 } | 12467 } |
| 12752 return &type; | 12468 return &type; |
| 12753 } | 12469 } |
| 12754 | 12470 |
| 12755 | |
| 12756 bool Parser::IsInstantiatorRequired() const { | 12471 bool Parser::IsInstantiatorRequired() const { |
| 12757 ASSERT(!current_function().IsNull()); | 12472 ASSERT(!current_function().IsNull()); |
| 12758 if (current_function().is_static() && | 12473 if (current_function().is_static() && |
| 12759 !current_function().IsInFactoryScope()) { | 12474 !current_function().IsInFactoryScope()) { |
| 12760 return false; | 12475 return false; |
| 12761 } | 12476 } |
| 12762 return current_class().IsGeneric(); | 12477 return current_class().IsGeneric(); |
| 12763 } | 12478 } |
| 12764 | 12479 |
| 12765 | |
| 12766 bool Parser::InGenericFunctionScope() const { | 12480 bool Parser::InGenericFunctionScope() const { |
| 12767 if (!innermost_function().IsNull()) { | 12481 if (!innermost_function().IsNull()) { |
| 12768 // With one more free tag bit in Function, we could cache this information. | 12482 // With one more free tag bit in Function, we could cache this information. |
| 12769 if (innermost_function().IsGeneric() || | 12483 if (innermost_function().IsGeneric() || |
| 12770 innermost_function().HasGenericParent()) { | 12484 innermost_function().HasGenericParent()) { |
| 12771 return true; | 12485 return true; |
| 12772 } | 12486 } |
| 12773 } | 12487 } |
| 12774 return false; | 12488 return false; |
| 12775 } | 12489 } |
| 12776 | 12490 |
| 12777 | |
| 12778 void Parser::InsertCachedConstantValue(const Script& script, | 12491 void Parser::InsertCachedConstantValue(const Script& script, |
| 12779 TokenPosition token_pos, | 12492 TokenPosition token_pos, |
| 12780 const Instance& value) { | 12493 const Instance& value) { |
| 12781 ASSERT(Thread::Current()->IsMutatorThread()); | 12494 ASSERT(Thread::Current()->IsMutatorThread()); |
| 12782 const intptr_t kInitialConstMapSize = 16; | 12495 const intptr_t kInitialConstMapSize = 16; |
| 12783 ASSERT(!script.InVMHeap()); | 12496 ASSERT(!script.InVMHeap()); |
| 12784 if (script.compile_time_constants() == Array::null()) { | 12497 if (script.compile_time_constants() == Array::null()) { |
| 12785 const Array& array = Array::Handle( | 12498 const Array& array = Array::Handle( |
| 12786 HashTables::New<ConstantsMap>(kInitialConstMapSize, Heap::kOld)); | 12499 HashTables::New<ConstantsMap>(kInitialConstMapSize, Heap::kOld)); |
| 12787 script.set_compile_time_constants(array); | 12500 script.set_compile_time_constants(array); |
| 12788 } | 12501 } |
| 12789 ConstantsMap constants(script.compile_time_constants()); | 12502 ConstantsMap constants(script.compile_time_constants()); |
| 12790 constants.InsertNewOrGetValue(token_pos, value); | 12503 constants.InsertNewOrGetValue(token_pos, value); |
| 12791 script.set_compile_time_constants(constants.Release()); | 12504 script.set_compile_time_constants(constants.Release()); |
| 12792 } | 12505 } |
| 12793 | 12506 |
| 12794 | |
| 12795 void Parser::CacheConstantValue(TokenPosition token_pos, | 12507 void Parser::CacheConstantValue(TokenPosition token_pos, |
| 12796 const Instance& value) { | 12508 const Instance& value) { |
| 12797 if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) { | 12509 if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) { |
| 12798 // Don't cache constants in initializer expressions. They get | 12510 // Don't cache constants in initializer expressions. They get |
| 12799 // evaluated only once. | 12511 // evaluated only once. |
| 12800 return; | 12512 return; |
| 12801 } | 12513 } |
| 12802 InsertCachedConstantValue(script_, token_pos, value); | 12514 InsertCachedConstantValue(script_, token_pos, value); |
| 12803 INC_STAT(thread_, num_cached_consts, 1); | 12515 INC_STAT(thread_, num_cached_consts, 1); |
| 12804 } | 12516 } |
| 12805 | 12517 |
| 12806 | |
| 12807 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) { | 12518 bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) { |
| 12808 bool is_present = false; | 12519 bool is_present = false; |
| 12809 ASSERT(!script_.InVMHeap()); | 12520 ASSERT(!script_.InVMHeap()); |
| 12810 if (script_.compile_time_constants() == Array::null()) { | 12521 if (script_.compile_time_constants() == Array::null()) { |
| 12811 return false; | 12522 return false; |
| 12812 } | 12523 } |
| 12813 ConstantsMap constants(script_.compile_time_constants()); | 12524 ConstantsMap constants(script_.compile_time_constants()); |
| 12814 *value ^= constants.GetOrNull(token_pos, &is_present); | 12525 *value ^= constants.GetOrNull(token_pos, &is_present); |
| 12815 // Mutator compiler thread may add constants while background compiler | 12526 // Mutator compiler thread may add constants while background compiler |
| 12816 // is running, and thus change the value of 'compile_time_constants'; | 12527 // is running, and thus change the value of 'compile_time_constants'; |
| 12817 // do not assert that 'compile_time_constants' has not changed. | 12528 // do not assert that 'compile_time_constants' has not changed. |
| 12818 constants.Release(); | 12529 constants.Release(); |
| 12819 if (FLAG_compiler_stats && is_present) { | 12530 if (FLAG_compiler_stats && is_present) { |
| 12820 thread_->compiler_stats()->num_const_cache_hits++; | 12531 thread_->compiler_stats()->num_const_cache_hits++; |
| 12821 } | 12532 } |
| 12822 return is_present; | 12533 return is_present; |
| 12823 } | 12534 } |
| 12824 | 12535 |
| 12825 | |
| 12826 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 12536 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 12827 TokenPosition token_pos) { | 12537 TokenPosition token_pos) { |
| 12828 if (instance.IsNull()) { | 12538 if (instance.IsNull()) { |
| 12829 return instance.raw(); | 12539 return instance.raw(); |
| 12830 } | 12540 } |
| 12831 const char* error_str = NULL; | 12541 const char* error_str = NULL; |
| 12832 Instance& result = | 12542 Instance& result = |
| 12833 Instance::Handle(Z, instance.CheckAndCanonicalize(thread(), &error_str)); | 12543 Instance::Handle(Z, instance.CheckAndCanonicalize(thread(), &error_str)); |
| 12834 if (result.IsNull()) { | 12544 if (result.IsNull()) { |
| 12835 ReportError(token_pos, "Invalid const object %s", error_str); | 12545 ReportError(token_pos, "Invalid const object %s", error_str); |
| 12836 } | 12546 } |
| 12837 return result.raw(); | 12547 return result.raw(); |
| 12838 } | 12548 } |
| 12839 | 12549 |
| 12840 | |
| 12841 // If the field is already initialized, return no ast (NULL). | 12550 // If the field is already initialized, return no ast (NULL). |
| 12842 // Otherwise, if the field is constant, initialize the field and return no ast. | 12551 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 12843 // If the field is not initialized and not const, return the ast for the getter. | 12552 // If the field is not initialized and not const, return the ast for the getter. |
| 12844 StaticGetterNode* Parser::RunStaticFieldInitializer( | 12553 StaticGetterNode* Parser::RunStaticFieldInitializer( |
| 12845 const Field& field, | 12554 const Field& field, |
| 12846 TokenPosition field_ref_pos) { | 12555 TokenPosition field_ref_pos) { |
| 12847 ASSERT(field.is_static()); | 12556 ASSERT(field.is_static()); |
| 12848 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); | 12557 const Class& field_owner = Class::ZoneHandle(Z, field.Owner()); |
| 12849 const String& field_name = String::ZoneHandle(Z, field.name()); | 12558 const String& field_name = String::ZoneHandle(Z, field.name()); |
| 12850 const String& getter_name = | 12559 const String& getter_name = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12909 } | 12618 } |
| 12910 } | 12619 } |
| 12911 if (getter.IsNull() || | 12620 if (getter.IsNull() || |
| 12912 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 12621 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
| 12913 return NULL; | 12622 return NULL; |
| 12914 } | 12623 } |
| 12915 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 12624 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 12916 return new (Z) StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); | 12625 return new (Z) StaticGetterNode(field_ref_pos, NULL, field_owner, field_name); |
| 12917 } | 12626 } |
| 12918 | 12627 |
| 12919 | |
| 12920 RawObject* Parser::EvaluateConstConstructorCall( | 12628 RawObject* Parser::EvaluateConstConstructorCall( |
| 12921 const Class& type_class, | 12629 const Class& type_class, |
| 12922 const TypeArguments& type_arguments, | 12630 const TypeArguments& type_arguments, |
| 12923 const Function& constructor, | 12631 const Function& constructor, |
| 12924 ArgumentListNode* arguments) { | 12632 ArgumentListNode* arguments) { |
| 12925 NoReloadScope no_reload_scope(isolate(), thread()); | 12633 NoReloadScope no_reload_scope(isolate(), thread()); |
| 12926 NoOOBMessageScope no_msg_scope(thread()); | 12634 NoOOBMessageScope no_msg_scope(thread()); |
| 12927 // Factories and constructors are not generic functions. | 12635 // Factories and constructors are not generic functions. |
| 12928 const int kTypeArgsLen = 0; | 12636 const int kTypeArgsLen = 0; |
| 12929 // Factories have one extra argument: the type arguments. | 12637 // Factories have one extra argument: the type arguments. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12973 } | 12681 } |
| 12974 } else { | 12682 } else { |
| 12975 if (constructor.IsFactory()) { | 12683 if (constructor.IsFactory()) { |
| 12976 // The factory method returns the allocated object. | 12684 // The factory method returns the allocated object. |
| 12977 instance ^= result.raw(); | 12685 instance ^= result.raw(); |
| 12978 } | 12686 } |
| 12979 return TryCanonicalize(instance, TokenPos()); | 12687 return TryCanonicalize(instance, TokenPos()); |
| 12980 } | 12688 } |
| 12981 } | 12689 } |
| 12982 | 12690 |
| 12983 | |
| 12984 // Do a lookup for the identifier in the block scope and the class scope | 12691 // Do a lookup for the identifier in the block scope and the class scope |
| 12985 // return true if the identifier is found, false otherwise. | 12692 // return true if the identifier is found, false otherwise. |
| 12986 // If node is non NULL return an AST node corresponding to the identifier. | 12693 // If node is non NULL return an AST node corresponding to the identifier. |
| 12987 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, | 12694 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, |
| 12988 const String& ident, | 12695 const String& ident, |
| 12989 AstNode** node, | 12696 AstNode** node, |
| 12990 intptr_t* function_level) { | 12697 intptr_t* function_level) { |
| 12991 TRACE_PARSER("ResolveIdentInLocalScope"); | 12698 TRACE_PARSER("ResolveIdentInLocalScope"); |
| 12992 // First try to find the identifier in the nested local scopes. | 12699 // First try to find the identifier in the nested local scopes. |
| 12993 LocalVariable* local = LookupLocalScope(ident); | 12700 LocalVariable* local = LookupLocalScope(ident); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13081 } | 12788 } |
| 13082 } | 12789 } |
| 13083 | 12790 |
| 13084 // Nothing found in scope of current class. | 12791 // Nothing found in scope of current class. |
| 13085 if (node != NULL) { | 12792 if (node != NULL) { |
| 13086 *node = NULL; | 12793 *node = NULL; |
| 13087 } | 12794 } |
| 13088 return false; | 12795 return false; |
| 13089 } | 12796 } |
| 13090 | 12797 |
| 13091 | |
| 13092 // Resolve an identifier by checking the global scope of the current | 12798 // Resolve an identifier by checking the global scope of the current |
| 13093 // library. If not found in the current library, then look in the scopes | 12799 // library. If not found in the current library, then look in the scopes |
| 13094 // of all libraries that are imported without a library prefix. | 12800 // of all libraries that are imported without a library prefix. |
| 13095 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, | 12801 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos, |
| 13096 const String& ident) { | 12802 const String& ident) { |
| 13097 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 12803 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
| 13098 HANDLESCOPE(thread()); | 12804 HANDLESCOPE(thread()); |
| 13099 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); | 12805 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
| 13100 if (obj.IsClass()) { | 12806 if (obj.IsClass()) { |
| 13101 const Class& cls = Class::Cast(obj); | 12807 const Class& cls = Class::Cast(obj); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 13125 const LibraryPrefix& prefix = LibraryPrefix::Cast(obj); | 12831 const LibraryPrefix& prefix = LibraryPrefix::Cast(obj); |
| 13126 ReportError(ident_pos, "illegal use of library prefix '%s'", | 12832 ReportError(ident_pos, "illegal use of library prefix '%s'", |
| 13127 String::Handle(prefix.name()).ToCString()); | 12833 String::Handle(prefix.name()).ToCString()); |
| 13128 } else { | 12834 } else { |
| 13129 ASSERT(obj.IsNull()); | 12835 ASSERT(obj.IsNull()); |
| 13130 } | 12836 } |
| 13131 // Lexically unresolved primary identifiers are referenced by their name. | 12837 // Lexically unresolved primary identifiers are referenced by their name. |
| 13132 return new (Z) PrimaryNode(ident_pos, ident); | 12838 return new (Z) PrimaryNode(ident_pos, ident); |
| 13133 } | 12839 } |
| 13134 | 12840 |
| 13135 | |
| 13136 // Do a lookup for the identifier in the scope of the specified | 12841 // Do a lookup for the identifier in the scope of the specified |
| 13137 // library prefix. This means trying to resolve it locally in all of the | 12842 // library prefix. This means trying to resolve it locally in all of the |
| 13138 // libraries present in the library prefix. | 12843 // libraries present in the library prefix. |
| 13139 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, | 12844 AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos, |
| 13140 const LibraryPrefix& prefix, | 12845 const LibraryPrefix& prefix, |
| 13141 const String& ident) { | 12846 const String& ident) { |
| 13142 TRACE_PARSER("ResolveIdentInPrefixScope"); | 12847 TRACE_PARSER("ResolveIdentInPrefixScope"); |
| 13143 HANDLESCOPE(thread()); | 12848 HANDLESCOPE(thread()); |
| 13144 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 12849 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
| 13145 // Private names are not exported by libraries. The name mangling | 12850 // Private names are not exported by libraries. The name mangling |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13204 primary->set_prefix(&prefix); | 12909 primary->set_prefix(&prefix); |
| 13205 } | 12910 } |
| 13206 return primary; | 12911 return primary; |
| 13207 } | 12912 } |
| 13208 } | 12913 } |
| 13209 // All possible object types are handled above. | 12914 // All possible object types are handled above. |
| 13210 UNREACHABLE(); | 12915 UNREACHABLE(); |
| 13211 return NULL; | 12916 return NULL; |
| 13212 } | 12917 } |
| 13213 | 12918 |
| 13214 | |
| 13215 // Resolve identifier. Issue an error message if | 12919 // Resolve identifier. Issue an error message if |
| 13216 // the ident refers to a method and allow_closure_names is false. | 12920 // the ident refers to a method and allow_closure_names is false. |
| 13217 // If the name cannot be resolved, turn it into an instance field access | 12921 // If the name cannot be resolved, turn it into an instance field access |
| 13218 // if we're compiling an instance method, or generate | 12922 // if we're compiling an instance method, or generate |
| 13219 // throw NoSuchMethodError if we're compiling a static method. | 12923 // throw NoSuchMethodError if we're compiling a static method. |
| 13220 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, | 12924 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, |
| 13221 const String& ident, | 12925 const String& ident, |
| 13222 bool allow_closure_names) { | 12926 bool allow_closure_names) { |
| 13223 TRACE_PARSER("ResolveIdent"); | 12927 TRACE_PARSER("ResolveIdent"); |
| 13224 // First try to find the variable in the local scope (block scope or | 12928 // First try to find the variable in the local scope (block scope or |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13295 type ^= CanonicalizeType(type); | 12999 type ^= CanonicalizeType(type); |
| 13296 // Type may be malbounded, but not malformed. | 13000 // Type may be malbounded, but not malformed. |
| 13297 ASSERT(!type.IsMalformed()); | 13001 ASSERT(!type.IsMalformed()); |
| 13298 resolved = | 13002 resolved = |
| 13299 new (Z) TypeNode(primary_pos, type, primary->is_deferred_reference()); | 13003 new (Z) TypeNode(primary_pos, type, primary->is_deferred_reference()); |
| 13300 } | 13004 } |
| 13301 } | 13005 } |
| 13302 return resolved; | 13006 return resolved; |
| 13303 } | 13007 } |
| 13304 | 13008 |
| 13305 | |
| 13306 RawAbstractType* Parser::ParseType( | 13009 RawAbstractType* Parser::ParseType( |
| 13307 ClassFinalizer::FinalizationKind finalization, | 13010 ClassFinalizer::FinalizationKind finalization, |
| 13308 bool allow_deferred_type, | 13011 bool allow_deferred_type, |
| 13309 bool consume_unresolved_prefix) { | 13012 bool consume_unresolved_prefix) { |
| 13310 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); | 13013 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); |
| 13311 return ParseType(finalization, allow_deferred_type, consume_unresolved_prefix, | 13014 return ParseType(finalization, allow_deferred_type, consume_unresolved_prefix, |
| 13312 &prefix); | 13015 &prefix); |
| 13313 } | 13016 } |
| 13314 | 13017 |
| 13315 | |
| 13316 // Parses and returns a type or a function type. | 13018 // Parses and returns a type or a function type. |
| 13317 RawAbstractType* Parser::ParseTypeOrFunctionType( | 13019 RawAbstractType* Parser::ParseTypeOrFunctionType( |
| 13318 bool allow_void, | 13020 bool allow_void, |
| 13319 ClassFinalizer::FinalizationKind finalization) { | 13021 ClassFinalizer::FinalizationKind finalization) { |
| 13320 TRACE_PARSER("ParseTypeOrFunctionType"); | 13022 TRACE_PARSER("ParseTypeOrFunctionType"); |
| 13321 AbstractType& type = AbstractType::Handle(Z); | 13023 AbstractType& type = AbstractType::Handle(Z); |
| 13322 if (CurrentToken() == Token::kVOID) { | 13024 if (CurrentToken() == Token::kVOID) { |
| 13323 TokenPosition void_pos = TokenPos(); | 13025 TokenPosition void_pos = TokenPos(); |
| 13324 type = Type::VoidType(); | 13026 type = Type::VoidType(); |
| 13325 ConsumeToken(); | 13027 ConsumeToken(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 13346 } | 13048 } |
| 13347 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13049 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
| 13348 ResolveType(&type); | 13050 ResolveType(&type); |
| 13349 if (finalization >= ClassFinalizer::kCanonicalize) { | 13051 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 13350 type ^= CanonicalizeType(type); | 13052 type ^= CanonicalizeType(type); |
| 13351 } | 13053 } |
| 13352 } | 13054 } |
| 13353 return type.raw(); | 13055 return type.raw(); |
| 13354 } | 13056 } |
| 13355 | 13057 |
| 13356 | |
| 13357 // Parses and returns a function type. | 13058 // Parses and returns a function type. |
| 13358 // If 'result_type' is not null, parsing of the result type is skipped. | 13059 // If 'result_type' is not null, parsing of the result type is skipped. |
| 13359 RawType* Parser::ParseFunctionType( | 13060 RawType* Parser::ParseFunctionType( |
| 13360 const AbstractType& result_type, | 13061 const AbstractType& result_type, |
| 13361 ClassFinalizer::FinalizationKind finalization) { | 13062 ClassFinalizer::FinalizationKind finalization) { |
| 13362 TRACE_PARSER("ParseFunctionType"); | 13063 TRACE_PARSER("ParseFunctionType"); |
| 13363 AbstractType& type = AbstractType::Handle(Z, result_type.raw()); | 13064 AbstractType& type = AbstractType::Handle(Z, result_type.raw()); |
| 13364 if (type.IsNull()) { | 13065 if (type.IsNull()) { |
| 13365 if (CurrentToken() == Token::kVOID) { | 13066 if (CurrentToken() == Token::kVOID) { |
| 13366 ConsumeToken(); | 13067 ConsumeToken(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13423 } | 13124 } |
| 13424 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13125 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
| 13425 ResolveType(&type); | 13126 ResolveType(&type); |
| 13426 if (finalization >= ClassFinalizer::kCanonicalize) { | 13127 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 13427 type ^= CanonicalizeType(type); | 13128 type ^= CanonicalizeType(type); |
| 13428 } | 13129 } |
| 13429 } | 13130 } |
| 13430 return Type::RawCast(type.raw()); | 13131 return Type::RawCast(type.raw()); |
| 13431 } | 13132 } |
| 13432 | 13133 |
| 13433 | |
| 13434 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 13134 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
| 13435 // finalize it according to the given type finalization mode. | 13135 // finalize it according to the given type finalization mode. |
| 13436 // Returns type and sets prefix. | 13136 // Returns type and sets prefix. |
| 13437 RawAbstractType* Parser::ParseType( | 13137 RawAbstractType* Parser::ParseType( |
| 13438 ClassFinalizer::FinalizationKind finalization, | 13138 ClassFinalizer::FinalizationKind finalization, |
| 13439 bool allow_deferred_type, | 13139 bool allow_deferred_type, |
| 13440 bool consume_unresolved_prefix, | 13140 bool consume_unresolved_prefix, |
| 13441 LibraryPrefix* prefix) { | 13141 LibraryPrefix* prefix) { |
| 13442 TRACE_PARSER("ParseType"); | 13142 TRACE_PARSER("ParseType"); |
| 13443 CheckToken(Token::kIDENT, "type name expected"); | 13143 CheckToken(Token::kIDENT, "type name expected"); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13510 } | 13210 } |
| 13511 // If the deferred prefixes are not allowed, or if the prefix is not yet | 13211 // If the deferred prefixes are not allowed, or if the prefix is not yet |
| 13512 // loaded when finalization is requested, return a malformed type. | 13212 // loaded when finalization is requested, return a malformed type. |
| 13513 // Otherwise, handle resolution below, as needed. | 13213 // Otherwise, handle resolution below, as needed. |
| 13514 if (!allow_deferred_type || | 13214 if (!allow_deferred_type || |
| 13515 (!prefix->is_loaded() && | 13215 (!prefix->is_loaded() && |
| 13516 (finalization > ClassFinalizer::kResolveTypeParameters))) { | 13216 (finalization > ClassFinalizer::kResolveTypeParameters))) { |
| 13517 ParseTypeArguments(ClassFinalizer::kIgnore); | 13217 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 13518 return ClassFinalizer::NewFinalizedMalformedType( | 13218 return ClassFinalizer::NewFinalizedMalformedType( |
| 13519 Error::Handle(Z), // No previous error. | 13219 Error::Handle(Z), // No previous error. |
| 13520 script_, ident_pos, !prefix->is_loaded() && allow_deferred_type | 13220 script_, ident_pos, |
| 13521 ? "deferred type '%s.%s' is not yet loaded" | 13221 !prefix->is_loaded() && allow_deferred_type |
| 13522 : "using deferred type '%s.%s' is invalid", | 13222 ? "deferred type '%s.%s' is not yet loaded" |
| 13223 : "using deferred type '%s.%s' is invalid", |
| 13523 String::Handle(Z, prefix->name()).ToCString(), | 13224 String::Handle(Z, prefix->name()).ToCString(), |
| 13524 type_name.ToCString()); | 13225 type_name.ToCString()); |
| 13525 } | 13226 } |
| 13526 } | 13227 } |
| 13527 } | 13228 } |
| 13528 Object& type_class = Object::Handle(Z); | 13229 Object& type_class = Object::Handle(Z); |
| 13529 // Leave type_class as null if type finalization mode is kIgnore. | 13230 // Leave type_class as null if type finalization mode is kIgnore. |
| 13530 if (finalization != ClassFinalizer::kIgnore) { | 13231 if (finalization != ClassFinalizer::kIgnore) { |
| 13531 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); | 13232 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); |
| 13532 } | 13233 } |
| 13533 TypeArguments& type_arguments = | 13234 TypeArguments& type_arguments = |
| 13534 TypeArguments::Handle(Z, ParseTypeArguments(finalization)); | 13235 TypeArguments::Handle(Z, ParseTypeArguments(finalization)); |
| 13535 if (finalization == ClassFinalizer::kIgnore) { | 13236 if (finalization == ClassFinalizer::kIgnore) { |
| 13536 return Type::DynamicType(); | 13237 return Type::DynamicType(); |
| 13537 } | 13238 } |
| 13538 AbstractType& type = AbstractType::Handle( | 13239 AbstractType& type = AbstractType::Handle( |
| 13539 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); | 13240 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); |
| 13540 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13241 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
| 13541 ResolveType(&type); | 13242 ResolveType(&type); |
| 13542 if (finalization >= ClassFinalizer::kCanonicalize) { | 13243 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 13543 type ^= CanonicalizeType(type); | 13244 type ^= CanonicalizeType(type); |
| 13544 } | 13245 } |
| 13545 } | 13246 } |
| 13546 return type.raw(); | 13247 return type.raw(); |
| 13547 } | 13248 } |
| 13548 | 13249 |
| 13549 | |
| 13550 void Parser::CheckConstructorCallTypeArguments( | 13250 void Parser::CheckConstructorCallTypeArguments( |
| 13551 TokenPosition pos, | 13251 TokenPosition pos, |
| 13552 const Function& constructor, | 13252 const Function& constructor, |
| 13553 const TypeArguments& type_arguments) { | 13253 const TypeArguments& type_arguments) { |
| 13554 if (!type_arguments.IsNull()) { | 13254 if (!type_arguments.IsNull()) { |
| 13555 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); | 13255 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
| 13556 ASSERT(!constructor_class.IsNull()); | 13256 ASSERT(!constructor_class.IsNull()); |
| 13557 ASSERT(constructor_class.is_finalized()); | 13257 ASSERT(constructor_class.is_finalized()); |
| 13558 ASSERT(type_arguments.IsCanonical()); | 13258 ASSERT(type_arguments.IsCanonical()); |
| 13559 // Do not report the expected vs. actual number of type arguments, because | 13259 // Do not report the expected vs. actual number of type arguments, because |
| 13560 // the type argument vector is flattened and raw types are allowed. | 13260 // the type argument vector is flattened and raw types are allowed. |
| 13561 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 13261 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
| 13562 ReportError(pos, "wrong number of type arguments passed to constructor"); | 13262 ReportError(pos, "wrong number of type arguments passed to constructor"); |
| 13563 } | 13263 } |
| 13564 } | 13264 } |
| 13565 } | 13265 } |
| 13566 | 13266 |
| 13567 | |
| 13568 // Parse "[" [ expr { "," expr } ["," ] "]". | 13267 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 13569 // Note: if the list literal is empty and the brackets have no whitespace | 13268 // Note: if the list literal is empty and the brackets have no whitespace |
| 13570 // between them, the scanner recognizes the opening and closing bracket | 13269 // between them, the scanner recognizes the opening and closing bracket |
| 13571 // as one token of type Token::kINDEX. | 13270 // as one token of type Token::kINDEX. |
| 13572 AstNode* Parser::ParseListLiteral(TokenPosition type_pos, | 13271 AstNode* Parser::ParseListLiteral(TokenPosition type_pos, |
| 13573 bool is_const, | 13272 bool is_const, |
| 13574 const TypeArguments& type_arguments) { | 13273 const TypeArguments& type_arguments) { |
| 13575 TRACE_PARSER("ParseListLiteral"); | 13274 TRACE_PARSER("ParseListLiteral"); |
| 13576 ASSERT(type_pos.IsReal()); | 13275 ASSERT(type_pos.IsReal()); |
| 13577 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 13276 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13720 factory_param->Add(empty_array_literal); | 13419 factory_param->Add(empty_array_literal); |
| 13721 } else { | 13420 } else { |
| 13722 ArrayNode* list = new (Z) ArrayNode(TokenPos(), type, element_list); | 13421 ArrayNode* list = new (Z) ArrayNode(TokenPos(), type, element_list); |
| 13723 factory_param->Add(list); | 13422 factory_param->Add(list); |
| 13724 } | 13423 } |
| 13725 return CreateConstructorCallNode(literal_pos, factory_type_args, | 13424 return CreateConstructorCallNode(literal_pos, factory_type_args, |
| 13726 factory_method, factory_param); | 13425 factory_method, factory_param); |
| 13727 } | 13426 } |
| 13728 } | 13427 } |
| 13729 | 13428 |
| 13730 | |
| 13731 ConstructorCallNode* Parser::CreateConstructorCallNode( | 13429 ConstructorCallNode* Parser::CreateConstructorCallNode( |
| 13732 TokenPosition token_pos, | 13430 TokenPosition token_pos, |
| 13733 const TypeArguments& type_arguments, | 13431 const TypeArguments& type_arguments, |
| 13734 const Function& constructor, | 13432 const Function& constructor, |
| 13735 ArgumentListNode* arguments) { | 13433 ArgumentListNode* arguments) { |
| 13736 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 13434 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
| 13737 EnsureExpressionTemp(); | 13435 EnsureExpressionTemp(); |
| 13738 } | 13436 } |
| 13739 return new (Z) | 13437 return new (Z) |
| 13740 ConstructorCallNode(token_pos, type_arguments, constructor, arguments); | 13438 ConstructorCallNode(token_pos, type_arguments, constructor, arguments); |
| 13741 } | 13439 } |
| 13742 | 13440 |
| 13743 | |
| 13744 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, | 13441 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, |
| 13745 bool is_const, | 13442 bool is_const, |
| 13746 AstNode* key, | 13443 AstNode* key, |
| 13747 AstNode* value) { | 13444 AstNode* value) { |
| 13748 if (is_const) { | 13445 if (is_const) { |
| 13749 ASSERT(key->IsLiteralNode()); | 13446 ASSERT(key->IsLiteralNode()); |
| 13750 const Instance& new_key = key->AsLiteralNode()->literal(); | 13447 const Instance& new_key = key->AsLiteralNode()->literal(); |
| 13751 for (int i = 0; i < pairs->length(); i += 2) { | 13448 for (int i = 0; i < pairs->length(); i += 2) { |
| 13752 const Instance& key_i = (*pairs)[i]->AsLiteralNode()->literal(); | 13449 const Instance& key_i = (*pairs)[i]->AsLiteralNode()->literal(); |
| 13753 // The keys of a compile time constant map are compile time | 13450 // The keys of a compile time constant map are compile time |
| 13754 // constants, i.e. canonicalized values. Thus, we can compare | 13451 // constants, i.e. canonicalized values. Thus, we can compare |
| 13755 // raw pointers to check for equality. | 13452 // raw pointers to check for equality. |
| 13756 if (new_key.raw() == key_i.raw()) { | 13453 if (new_key.raw() == key_i.raw()) { |
| 13757 // Duplicate key found. The new value replaces the previously | 13454 // Duplicate key found. The new value replaces the previously |
| 13758 // defined value. | 13455 // defined value. |
| 13759 (*pairs)[i + 1] = value; | 13456 (*pairs)[i + 1] = value; |
| 13760 return; | 13457 return; |
| 13761 } | 13458 } |
| 13762 } | 13459 } |
| 13763 } | 13460 } |
| 13764 pairs->Add(key); | 13461 pairs->Add(key); |
| 13765 pairs->Add(value); | 13462 pairs->Add(value); |
| 13766 } | 13463 } |
| 13767 | 13464 |
| 13768 | |
| 13769 AstNode* Parser::ParseMapLiteral(TokenPosition type_pos, | 13465 AstNode* Parser::ParseMapLiteral(TokenPosition type_pos, |
| 13770 bool is_const, | 13466 bool is_const, |
| 13771 const TypeArguments& type_arguments) { | 13467 const TypeArguments& type_arguments) { |
| 13772 TRACE_PARSER("ParseMapLiteral"); | 13468 TRACE_PARSER("ParseMapLiteral"); |
| 13773 ASSERT(type_pos.IsReal()); | 13469 ASSERT(type_pos.IsReal()); |
| 13774 ASSERT(CurrentToken() == Token::kLBRACE); | 13470 ASSERT(CurrentToken() == Token::kLBRACE); |
| 13775 const TokenPosition literal_pos = TokenPos(); | 13471 const TokenPosition literal_pos = TokenPos(); |
| 13776 | 13472 |
| 13777 if (is_const) { | 13473 if (is_const) { |
| 13778 Instance& existing_const = Instance::ZoneHandle(Z); | 13474 Instance& existing_const = Instance::ZoneHandle(Z); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13978 factory_param->Add(kv_pairs); | 13674 factory_param->Add(kv_pairs); |
| 13979 } | 13675 } |
| 13980 | 13676 |
| 13981 return CreateConstructorCallNode(literal_pos, factory_type_args, | 13677 return CreateConstructorCallNode(literal_pos, factory_type_args, |
| 13982 factory_method, factory_param); | 13678 factory_method, factory_param); |
| 13983 } | 13679 } |
| 13984 UNREACHABLE(); | 13680 UNREACHABLE(); |
| 13985 return NULL; | 13681 return NULL; |
| 13986 } | 13682 } |
| 13987 | 13683 |
| 13988 | |
| 13989 AstNode* Parser::ParseCompoundLiteral() { | 13684 AstNode* Parser::ParseCompoundLiteral() { |
| 13990 TRACE_PARSER("ParseCompoundLiteral"); | 13685 TRACE_PARSER("ParseCompoundLiteral"); |
| 13991 bool is_const = false; | 13686 bool is_const = false; |
| 13992 if (CurrentToken() == Token::kCONST) { | 13687 if (CurrentToken() == Token::kCONST) { |
| 13993 is_const = true; | 13688 is_const = true; |
| 13994 ConsumeToken(); | 13689 ConsumeToken(); |
| 13995 } | 13690 } |
| 13996 const TokenPosition type_pos = TokenPos(); | 13691 const TokenPosition type_pos = TokenPos(); |
| 13997 TypeArguments& type_arguments = TypeArguments::Handle( | 13692 TypeArguments& type_arguments = TypeArguments::Handle( |
| 13998 Z, ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 13693 Z, ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
| 13999 // Malformed type arguments are mapped to dynamic, so we will not encounter | 13694 // Malformed type arguments are mapped to dynamic, so we will not encounter |
| 14000 // them here. | 13695 // them here. |
| 14001 // Map and List interfaces do not declare bounds on their type parameters, so | 13696 // Map and List interfaces do not declare bounds on their type parameters, so |
| 14002 // we will not see malbounded type arguments here. | 13697 // we will not see malbounded type arguments here. |
| 14003 AstNode* primary = NULL; | 13698 AstNode* primary = NULL; |
| 14004 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { | 13699 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { |
| 14005 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 13700 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 14006 } else if (CurrentToken() == Token::kLBRACE) { | 13701 } else if (CurrentToken() == Token::kLBRACE) { |
| 14007 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 13702 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 14008 } else { | 13703 } else { |
| 14009 UnexpectedToken(); | 13704 UnexpectedToken(); |
| 14010 } | 13705 } |
| 14011 return primary; | 13706 return primary; |
| 14012 } | 13707 } |
| 14013 | 13708 |
| 14014 | |
| 14015 AstNode* Parser::ParseSymbolLiteral() { | 13709 AstNode* Parser::ParseSymbolLiteral() { |
| 14016 ASSERT(CurrentToken() == Token::kHASH); | 13710 ASSERT(CurrentToken() == Token::kHASH); |
| 14017 ConsumeToken(); | 13711 ConsumeToken(); |
| 14018 TokenPosition symbol_pos = TokenPos(); | 13712 TokenPosition symbol_pos = TokenPos(); |
| 14019 String& symbol = String::ZoneHandle(Z); | 13713 String& symbol = String::ZoneHandle(Z); |
| 14020 if (IsIdentifier()) { | 13714 if (IsIdentifier()) { |
| 14021 symbol = CurrentLiteral()->raw(); | 13715 symbol = CurrentLiteral()->raw(); |
| 14022 ConsumeToken(); | 13716 ConsumeToken(); |
| 14023 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13717 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 14024 pieces.Add(symbol); | 13718 pieces.Add(symbol); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 14054 constr, constr_args)); | 13748 constr, constr_args)); |
| 14055 if (result.IsUnhandledException()) { | 13749 if (result.IsUnhandledException()) { |
| 14056 ReportErrors(Error::Cast(result), script_, symbol_pos, | 13750 ReportErrors(Error::Cast(result), script_, symbol_pos, |
| 14057 "error executing const Symbol constructor"); | 13751 "error executing const Symbol constructor"); |
| 14058 } | 13752 } |
| 14059 symbol_instance ^= result.raw(); | 13753 symbol_instance ^= result.raw(); |
| 14060 CacheConstantValue(symbol_pos, symbol_instance); | 13754 CacheConstantValue(symbol_pos, symbol_instance); |
| 14061 return new (Z) LiteralNode(symbol_pos, symbol_instance); | 13755 return new (Z) LiteralNode(symbol_pos, symbol_instance); |
| 14062 } | 13756 } |
| 14063 | 13757 |
| 14064 | |
| 14065 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, | 13758 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, |
| 14066 TokenPosition token_pos) { | 13759 TokenPosition token_pos) { |
| 14067 ASSERT(ctr.kind() == RawFunction::kConstructor); | 13760 ASSERT(ctr.kind() == RawFunction::kConstructor); |
| 14068 Function& closure = Function::Handle(Z); | 13761 Function& closure = Function::Handle(Z); |
| 14069 closure = I->LookupClosureFunction(innermost_function(), token_pos); | 13762 closure = I->LookupClosureFunction(innermost_function(), token_pos); |
| 14070 if (!closure.IsNull()) { | 13763 if (!closure.IsNull()) { |
| 14071 ASSERT(closure.IsConstructorClosureFunction()); | 13764 ASSERT(closure.IsConstructorClosureFunction()); |
| 14072 return closure.raw(); | 13765 return closure.raw(); |
| 14073 } | 13766 } |
| 14074 | 13767 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 14097 | 13790 |
| 14098 // Finalize function type. | 13791 // Finalize function type. |
| 14099 Type& signature_type = Type::Handle(Z, closure.SignatureType()); | 13792 Type& signature_type = Type::Handle(Z, closure.SignatureType()); |
| 14100 signature_type ^= CanonicalizeType(signature_type); | 13793 signature_type ^= CanonicalizeType(signature_type); |
| 14101 closure.SetSignatureType(signature_type); | 13794 closure.SetSignatureType(signature_type); |
| 14102 // Finalization would be premature when top-level parsing. | 13795 // Finalization would be premature when top-level parsing. |
| 14103 ASSERT(!is_top_level_); | 13796 ASSERT(!is_top_level_); |
| 14104 return closure.raw(); | 13797 return closure.raw(); |
| 14105 } | 13798 } |
| 14106 | 13799 |
| 14107 | |
| 14108 static String& BuildConstructorName(Thread* thread, | 13800 static String& BuildConstructorName(Thread* thread, |
| 14109 const String& type_class_name, | 13801 const String& type_class_name, |
| 14110 const String* named_constructor) { | 13802 const String* named_constructor) { |
| 14111 // By convention, the static function implementing a named constructor 'C' | 13803 // By convention, the static function implementing a named constructor 'C' |
| 14112 // for class 'A' is labeled 'A.C', and the static function implementing the | 13804 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 14113 // unnamed constructor for class 'A' is labeled 'A.'. | 13805 // unnamed constructor for class 'A' is labeled 'A.'. |
| 14114 // This convention prevents users from explicitly calling constructors. | 13806 // This convention prevents users from explicitly calling constructors. |
| 14115 Zone* zone = thread->zone(); | 13807 Zone* zone = thread->zone(); |
| 14116 String& constructor_name = | 13808 String& constructor_name = |
| 14117 String::Handle(zone, Symbols::FromDot(thread, type_class_name)); | 13809 String::Handle(zone, Symbols::FromDot(thread, type_class_name)); |
| 14118 if (named_constructor != NULL) { | 13810 if (named_constructor != NULL) { |
| 14119 constructor_name = | 13811 constructor_name = |
| 14120 Symbols::FromConcat(thread, constructor_name, *named_constructor); | 13812 Symbols::FromConcat(thread, constructor_name, *named_constructor); |
| 14121 } | 13813 } |
| 14122 return constructor_name; | 13814 return constructor_name; |
| 14123 } | 13815 } |
| 14124 | 13816 |
| 14125 | |
| 14126 // Parse a primary expression of the form new T# or new T#m. | 13817 // Parse a primary expression of the form new T# or new T#m. |
| 14127 // Current token position is after the keyword new. Extracts the | 13818 // Current token position is after the keyword new. Extracts the |
| 14128 // anonymous or named constructor and type arguments. | 13819 // anonymous or named constructor and type arguments. |
| 14129 // Note that type type T has already been parsed before | 13820 // Note that type type T has already been parsed before |
| 14130 // (by ParseNewOperator()) and is guaranteed to be well-formed, | 13821 // (by ParseNewOperator()) and is guaranteed to be well-formed, |
| 14131 // and the constructor is known to exist. | 13822 // and the constructor is known to exist. |
| 14132 void Parser::ParseConstructorClosurization(Function* constructor, | 13823 void Parser::ParseConstructorClosurization(Function* constructor, |
| 14133 TypeArguments* type_arguments) { | 13824 TypeArguments* type_arguments) { |
| 14134 *constructor = Function::null(); | 13825 *constructor = Function::null(); |
| 14135 *type_arguments = TypeArguments::null(); | 13826 *type_arguments = TypeArguments::null(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14178 NULL, // bound_trail | 13869 NULL, // bound_trail |
| 14179 Heap::kOld); | 13870 Heap::kOld); |
| 14180 ASSERT(error.IsNull()); | 13871 ASSERT(error.IsNull()); |
| 14181 } | 13872 } |
| 14182 *type_arguments = type.arguments(); | 13873 *type_arguments = type.arguments(); |
| 14183 *constructor = constructor->RedirectionTarget(); | 13874 *constructor = constructor->RedirectionTarget(); |
| 14184 } | 13875 } |
| 14185 } | 13876 } |
| 14186 } | 13877 } |
| 14187 | 13878 |
| 14188 | |
| 14189 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13879 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
| 14190 TRACE_PARSER("ParseNewOperator"); | 13880 TRACE_PARSER("ParseNewOperator"); |
| 14191 const TokenPosition new_pos = TokenPos(); | 13881 const TokenPosition new_pos = TokenPos(); |
| 14192 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13882 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
| 14193 bool is_const = (op_kind == Token::kCONST); | 13883 bool is_const = (op_kind == Token::kCONST); |
| 14194 if (!IsIdentifier()) { | 13884 if (!IsIdentifier()) { |
| 14195 ReportError("type name expected"); | 13885 ReportError("type name expected"); |
| 14196 } | 13886 } |
| 14197 TokenPosition type_pos = TokenPos(); | 13887 TokenPosition type_pos = TokenPos(); |
| 14198 // Can't allocate const objects of a deferred type. | 13888 // Can't allocate const objects of a deferred type. |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14532 new_object = CreateConstructorCallNode(new_pos, type_arguments, constructor, | 14222 new_object = CreateConstructorCallNode(new_pos, type_arguments, constructor, |
| 14533 arguments); | 14223 arguments); |
| 14534 } | 14224 } |
| 14535 if (!type_bound.IsNull()) { | 14225 if (!type_bound.IsNull()) { |
| 14536 new_object = new (Z) AssignableNode(new_pos, new_object, type_bound, | 14226 new_object = new (Z) AssignableNode(new_pos, new_object, type_bound, |
| 14537 Symbols::FactoryResult()); | 14227 Symbols::FactoryResult()); |
| 14538 } | 14228 } |
| 14539 return new_object; | 14229 return new_object; |
| 14540 } | 14230 } |
| 14541 | 14231 |
| 14542 | |
| 14543 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { | 14232 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { |
| 14544 NoReloadScope no_reload_scope(isolate(), thread()); | 14233 NoReloadScope no_reload_scope(isolate(), thread()); |
| 14545 NoOOBMessageScope no_msg_scope(thread()); | 14234 NoOOBMessageScope no_msg_scope(thread()); |
| 14546 const Class& cls = | 14235 const Class& cls = |
| 14547 Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase())); | 14236 Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase())); |
| 14548 ASSERT(!cls.IsNull()); | 14237 ASSERT(!cls.IsNull()); |
| 14549 const Function& func = Function::Handle( | 14238 const Function& func = Function::Handle( |
| 14550 Z, cls.LookupStaticFunction( | 14239 Z, cls.LookupStaticFunction( |
| 14551 Library::PrivateCoreLibName(Symbols::Interpolate()))); | 14240 Library::PrivateCoreLibName(Symbols::Interpolate()))); |
| 14552 ASSERT(!func.IsNull()); | 14241 ASSERT(!func.IsNull()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 14568 result = DartEntry::InvokeFunction(func, interpolate_arg); | 14257 result = DartEntry::InvokeFunction(func, interpolate_arg); |
| 14569 if (result.IsUnhandledException()) { | 14258 if (result.IsUnhandledException()) { |
| 14570 ReportError("%s", Error::Cast(result).ToErrorCString()); | 14259 ReportError("%s", Error::Cast(result).ToErrorCString()); |
| 14571 } | 14260 } |
| 14572 String& concatenated = String::ZoneHandle(Z); | 14261 String& concatenated = String::ZoneHandle(Z); |
| 14573 concatenated ^= result.raw(); | 14262 concatenated ^= result.raw(); |
| 14574 concatenated = Symbols::New(T, concatenated); | 14263 concatenated = Symbols::New(T, concatenated); |
| 14575 return concatenated; | 14264 return concatenated; |
| 14576 } | 14265 } |
| 14577 | 14266 |
| 14578 | |
| 14579 // A string literal consists of the concatenation of the next n tokens | 14267 // A string literal consists of the concatenation of the next n tokens |
| 14580 // that satisfy the EBNF grammar: | 14268 // that satisfy the EBNF grammar: |
| 14581 // literal = kSTRING {{ interpol } kSTRING } | 14269 // literal = kSTRING {{ interpol } kSTRING } |
| 14582 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 14270 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 14583 // In other words, the scanner breaks down interpolated strings so that | 14271 // In other words, the scanner breaks down interpolated strings so that |
| 14584 // a string literal always begins and ends with a kSTRING token. | 14272 // a string literal always begins and ends with a kSTRING token. |
| 14585 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 14273 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
| 14586 TRACE_PARSER("ParseStringLiteral"); | 14274 TRACE_PARSER("ParseStringLiteral"); |
| 14587 AstNode* primary = NULL; | 14275 AstNode* primary = NULL; |
| 14588 const TokenPosition literal_start = TokenPos(); | 14276 const TokenPosition literal_start = TokenPos(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14673 // find the value next time. | 14361 // find the value next time. |
| 14674 } | 14362 } |
| 14675 } else { | 14363 } else { |
| 14676 ArrayNode* values = new (Z) ArrayNode( | 14364 ArrayNode* values = new (Z) ArrayNode( |
| 14677 TokenPos(), Type::ZoneHandle(Z, Type::ArrayType()), values_list); | 14365 TokenPos(), Type::ZoneHandle(Z, Type::ArrayType()), values_list); |
| 14678 primary = new (Z) StringInterpolateNode(TokenPos(), values); | 14366 primary = new (Z) StringInterpolateNode(TokenPos(), values); |
| 14679 } | 14367 } |
| 14680 return primary; | 14368 return primary; |
| 14681 } | 14369 } |
| 14682 | 14370 |
| 14683 | |
| 14684 AstNode* Parser::ParsePrimary() { | 14371 AstNode* Parser::ParsePrimary() { |
| 14685 TRACE_PARSER("ParsePrimary"); | 14372 TRACE_PARSER("ParsePrimary"); |
| 14686 ASSERT(!is_top_level_); | 14373 ASSERT(!is_top_level_); |
| 14687 AstNode* primary = NULL; | 14374 AstNode* primary = NULL; |
| 14688 const Token::Kind token = CurrentToken(); | 14375 const Token::Kind token = CurrentToken(); |
| 14689 if (IsFunctionLiteral()) { | 14376 if (IsFunctionLiteral()) { |
| 14690 primary = ParseFunctionStatement(true); | 14377 primary = ParseFunctionStatement(true); |
| 14691 } else if (IsIdentifier()) { | 14378 } else if (IsIdentifier()) { |
| 14692 TokenPosition qual_ident_pos = TokenPos(); | 14379 TokenPosition qual_ident_pos = TokenPos(); |
| 14693 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 14380 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14886 ReportError("super call or super getter may not use ?."); | 14573 ReportError("super call or super getter may not use ?."); |
| 14887 } else { | 14574 } else { |
| 14888 primary = new (Z) PrimaryNode(super_pos, Symbols::Super()); | 14575 primary = new (Z) PrimaryNode(super_pos, Symbols::Super()); |
| 14889 } | 14576 } |
| 14890 } else { | 14577 } else { |
| 14891 UnexpectedToken(); | 14578 UnexpectedToken(); |
| 14892 } | 14579 } |
| 14893 return primary; | 14580 return primary; |
| 14894 } | 14581 } |
| 14895 | 14582 |
| 14896 | |
| 14897 // Evaluate expression in expr and return the value. The expression must | 14583 // Evaluate expression in expr and return the value. The expression must |
| 14898 // be a compile time constant. | 14584 // be a compile time constant. |
| 14899 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, | 14585 const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos, |
| 14900 AstNode* expr) { | 14586 AstNode* expr) { |
| 14901 NoReloadScope no_reload_scope(isolate(), thread()); | 14587 NoReloadScope no_reload_scope(isolate(), thread()); |
| 14902 NoOOBMessageScope no_msg_scope(thread()); | 14588 NoOOBMessageScope no_msg_scope(thread()); |
| 14903 if (expr->IsLiteralNode()) { | 14589 if (expr->IsLiteralNode()) { |
| 14904 return expr->AsLiteralNode()->literal(); | 14590 return expr->AsLiteralNode()->literal(); |
| 14905 } else if (expr->IsLoadLocalNode() && | 14591 } else if (expr->IsLoadLocalNode() && |
| 14906 expr->AsLoadLocalNode()->local().IsConst()) { | 14592 expr->AsLoadLocalNode()->local().IsConst()) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14944 "error evaluating constant expression"); | 14630 "error evaluating constant expression"); |
| 14945 } | 14631 } |
| 14946 ASSERT(result.IsInstance() || result.IsNull()); | 14632 ASSERT(result.IsInstance() || result.IsNull()); |
| 14947 value ^= result.raw(); | 14633 value ^= result.raw(); |
| 14948 value = TryCanonicalize(value, expr_pos); | 14634 value = TryCanonicalize(value, expr_pos); |
| 14949 CacheConstantValue(expr_pos, value); | 14635 CacheConstantValue(expr_pos, value); |
| 14950 return value; | 14636 return value; |
| 14951 } | 14637 } |
| 14952 } | 14638 } |
| 14953 | 14639 |
| 14954 | |
| 14955 void Parser::SkipFunctionLiteral() { | 14640 void Parser::SkipFunctionLiteral() { |
| 14956 if (IsIdentifier()) { | 14641 if (IsIdentifier()) { |
| 14957 if (LookaheadToken(1) != Token::kLPAREN) { | 14642 if (LookaheadToken(1) != Token::kLPAREN) { |
| 14958 SkipTypeOrFunctionType(true); | 14643 SkipTypeOrFunctionType(true); |
| 14959 } | 14644 } |
| 14960 ExpectIdentifier("function name expected"); | 14645 ExpectIdentifier("function name expected"); |
| 14961 } | 14646 } |
| 14962 if (CurrentToken() == Token::kLPAREN) { | 14647 if (CurrentToken() == Token::kLPAREN) { |
| 14963 SkipToMatchingParenthesis(); | 14648 SkipToMatchingParenthesis(); |
| 14964 } | 14649 } |
| 14965 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 14650 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
| 14966 BoolScope allow_await(&this->await_is_keyword_, | 14651 BoolScope allow_await(&this->await_is_keyword_, |
| 14967 async_modifier != RawFunction::kNoModifier); | 14652 async_modifier != RawFunction::kNoModifier); |
| 14968 if (CurrentToken() == Token::kLBRACE) { | 14653 if (CurrentToken() == Token::kLBRACE) { |
| 14969 SkipBlock(); | 14654 SkipBlock(); |
| 14970 ExpectToken(Token::kRBRACE); | 14655 ExpectToken(Token::kRBRACE); |
| 14971 } else if (CurrentToken() == Token::kARROW) { | 14656 } else if (CurrentToken() == Token::kARROW) { |
| 14972 ConsumeToken(); | 14657 ConsumeToken(); |
| 14973 SkipExpr(); | 14658 SkipExpr(); |
| 14974 } | 14659 } |
| 14975 } | 14660 } |
| 14976 | 14661 |
| 14977 | |
| 14978 // Skips function/method/constructor/getter/setter preambles until the formal | 14662 // Skips function/method/constructor/getter/setter preambles until the formal |
| 14979 // parameter list. It is enough to skip the tokens, since we have already | 14663 // parameter list. It is enough to skip the tokens, since we have already |
| 14980 // previously parsed the function. | 14664 // previously parsed the function. |
| 14981 void Parser::SkipFunctionPreamble() { | 14665 void Parser::SkipFunctionPreamble() { |
| 14982 while (true) { | 14666 while (true) { |
| 14983 if (IsFunctionTypeSymbol()) { | 14667 if (IsFunctionTypeSymbol()) { |
| 14984 ConsumeToken(); | 14668 ConsumeToken(); |
| 14985 SkipTypeParameters(); | 14669 SkipTypeParameters(); |
| 14986 SkipToMatchingParenthesis(); | 14670 SkipToMatchingParenthesis(); |
| 14987 continue; | 14671 continue; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 15004 } | 14688 } |
| 15005 // Case: Getter. | 14689 // Case: Getter. |
| 15006 ConsumeToken(); // Parse away 'get'. | 14690 ConsumeToken(); // Parse away 'get'. |
| 15007 ConsumeToken(); // Parse away the getter name. | 14691 ConsumeToken(); // Parse away the getter name. |
| 15008 return; | 14692 return; |
| 15009 } | 14693 } |
| 15010 ConsumeToken(); // Can be static, factory, operator, void, ident, etc... | 14694 ConsumeToken(); // Can be static, factory, operator, void, ident, etc... |
| 15011 } | 14695 } |
| 15012 } | 14696 } |
| 15013 | 14697 |
| 15014 | |
| 15015 void Parser::SkipListLiteral() { | 14698 void Parser::SkipListLiteral() { |
| 15016 if (CurrentToken() == Token::kINDEX) { | 14699 if (CurrentToken() == Token::kINDEX) { |
| 15017 // Empty list literal. | 14700 // Empty list literal. |
| 15018 ConsumeToken(); | 14701 ConsumeToken(); |
| 15019 return; | 14702 return; |
| 15020 } | 14703 } |
| 15021 ExpectToken(Token::kLBRACK); | 14704 ExpectToken(Token::kLBRACK); |
| 15022 while (CurrentToken() != Token::kRBRACK) { | 14705 while (CurrentToken() != Token::kRBRACK) { |
| 15023 SkipNestedExpr(); | 14706 SkipNestedExpr(); |
| 15024 if (CurrentToken() == Token::kCOMMA) { | 14707 if (CurrentToken() == Token::kCOMMA) { |
| 15025 ConsumeToken(); | 14708 ConsumeToken(); |
| 15026 } else { | 14709 } else { |
| 15027 break; | 14710 break; |
| 15028 } | 14711 } |
| 15029 } | 14712 } |
| 15030 ExpectToken(Token::kRBRACK); | 14713 ExpectToken(Token::kRBRACK); |
| 15031 } | 14714 } |
| 15032 | 14715 |
| 15033 | |
| 15034 void Parser::SkipMapLiteral() { | 14716 void Parser::SkipMapLiteral() { |
| 15035 ExpectToken(Token::kLBRACE); | 14717 ExpectToken(Token::kLBRACE); |
| 15036 while (CurrentToken() != Token::kRBRACE) { | 14718 while (CurrentToken() != Token::kRBRACE) { |
| 15037 SkipNestedExpr(); | 14719 SkipNestedExpr(); |
| 15038 ExpectToken(Token::kCOLON); | 14720 ExpectToken(Token::kCOLON); |
| 15039 SkipNestedExpr(); | 14721 SkipNestedExpr(); |
| 15040 if (CurrentToken() == Token::kCOMMA) { | 14722 if (CurrentToken() == Token::kCOMMA) { |
| 15041 ConsumeToken(); | 14723 ConsumeToken(); |
| 15042 } else { | 14724 } else { |
| 15043 break; | 14725 break; |
| 15044 } | 14726 } |
| 15045 } | 14727 } |
| 15046 ExpectToken(Token::kRBRACE); | 14728 ExpectToken(Token::kRBRACE); |
| 15047 } | 14729 } |
| 15048 | 14730 |
| 15049 | |
| 15050 void Parser::SkipActualParameters() { | 14731 void Parser::SkipActualParameters() { |
| 15051 if (CurrentToken() == Token::kLT) { | 14732 if (CurrentToken() == Token::kLT) { |
| 15052 SkipTypeArguments(); | 14733 SkipTypeArguments(); |
| 15053 } | 14734 } |
| 15054 ExpectToken(Token::kLPAREN); | 14735 ExpectToken(Token::kLPAREN); |
| 15055 while (CurrentToken() != Token::kRPAREN) { | 14736 while (CurrentToken() != Token::kRPAREN) { |
| 15056 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 14737 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 15057 // Named actual parameter. | 14738 // Named actual parameter. |
| 15058 ConsumeToken(); | 14739 ConsumeToken(); |
| 15059 ConsumeToken(); | 14740 ConsumeToken(); |
| 15060 } | 14741 } |
| 15061 SkipNestedExpr(); | 14742 SkipNestedExpr(); |
| 15062 if (CurrentToken() == Token::kCOMMA) { | 14743 if (CurrentToken() == Token::kCOMMA) { |
| 15063 ConsumeToken(); | 14744 ConsumeToken(); |
| 15064 } | 14745 } |
| 15065 } | 14746 } |
| 15066 ExpectToken(Token::kRPAREN); | 14747 ExpectToken(Token::kRPAREN); |
| 15067 } | 14748 } |
| 15068 | 14749 |
| 15069 | |
| 15070 void Parser::SkipCompoundLiteral() { | 14750 void Parser::SkipCompoundLiteral() { |
| 15071 if (CurrentToken() == Token::kLT) { | 14751 if (CurrentToken() == Token::kLT) { |
| 15072 SkipTypeArguments(); | 14752 SkipTypeArguments(); |
| 15073 } | 14753 } |
| 15074 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { | 14754 if ((CurrentToken() == Token::kLBRACK) || (CurrentToken() == Token::kINDEX)) { |
| 15075 SkipListLiteral(); | 14755 SkipListLiteral(); |
| 15076 } else if (CurrentToken() == Token::kLBRACE) { | 14756 } else if (CurrentToken() == Token::kLBRACE) { |
| 15077 SkipMapLiteral(); | 14757 SkipMapLiteral(); |
| 15078 } | 14758 } |
| 15079 } | 14759 } |
| 15080 | 14760 |
| 15081 | |
| 15082 void Parser::SkipSymbolLiteral() { | 14761 void Parser::SkipSymbolLiteral() { |
| 15083 ConsumeToken(); // Hash sign. | 14762 ConsumeToken(); // Hash sign. |
| 15084 if (IsIdentifier()) { | 14763 if (IsIdentifier()) { |
| 15085 ConsumeToken(); | 14764 ConsumeToken(); |
| 15086 while (CurrentToken() == Token::kPERIOD) { | 14765 while (CurrentToken() == Token::kPERIOD) { |
| 15087 ConsumeToken(); | 14766 ConsumeToken(); |
| 15088 ExpectIdentifier("identifier expected"); | 14767 ExpectIdentifier("identifier expected"); |
| 15089 } | 14768 } |
| 15090 } else if (Token::CanBeOverloaded(CurrentToken())) { | 14769 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 15091 ConsumeToken(); | 14770 ConsumeToken(); |
| 15092 } else { | 14771 } else { |
| 15093 UnexpectedToken(); | 14772 UnexpectedToken(); |
| 15094 } | 14773 } |
| 15095 } | 14774 } |
| 15096 | 14775 |
| 15097 | |
| 15098 void Parser::SkipNewOperator() { | 14776 void Parser::SkipNewOperator() { |
| 15099 ConsumeToken(); // Skip new or const keyword. | 14777 ConsumeToken(); // Skip new or const keyword. |
| 15100 if (IsIdentifier()) { | 14778 if (IsIdentifier()) { |
| 15101 SkipType(false); | 14779 SkipType(false); |
| 15102 if (CurrentToken() == Token::kPERIOD) { | 14780 if (CurrentToken() == Token::kPERIOD) { |
| 15103 ConsumeToken(); | 14781 ConsumeToken(); |
| 15104 ExpectIdentifier("identifier expected"); | 14782 ExpectIdentifier("identifier expected"); |
| 15105 } else if (CurrentToken() == Token::kHASH) { | 14783 } else if (CurrentToken() == Token::kHASH) { |
| 15106 ConsumeToken(); | 14784 ConsumeToken(); |
| 15107 if (IsIdentifier()) { | 14785 if (IsIdentifier()) { |
| 15108 ConsumeToken(); | 14786 ConsumeToken(); |
| 15109 } | 14787 } |
| 15110 return; | 14788 return; |
| 15111 } | 14789 } |
| 15112 if (CurrentToken() == Token::kLPAREN) { | 14790 if (CurrentToken() == Token::kLPAREN) { |
| 15113 SkipActualParameters(); | 14791 SkipActualParameters(); |
| 15114 return; | 14792 return; |
| 15115 } | 14793 } |
| 15116 } | 14794 } |
| 15117 } | 14795 } |
| 15118 | 14796 |
| 15119 | |
| 15120 void Parser::SkipStringLiteral() { | 14797 void Parser::SkipStringLiteral() { |
| 15121 ASSERT(CurrentToken() == Token::kSTRING); | 14798 ASSERT(CurrentToken() == Token::kSTRING); |
| 15122 while (CurrentToken() == Token::kSTRING) { | 14799 while (CurrentToken() == Token::kSTRING) { |
| 15123 ConsumeToken(); | 14800 ConsumeToken(); |
| 15124 while (true) { | 14801 while (true) { |
| 15125 if (CurrentToken() == Token::kINTERPOL_VAR) { | 14802 if (CurrentToken() == Token::kINTERPOL_VAR) { |
| 15126 ConsumeToken(); | 14803 ConsumeToken(); |
| 15127 } else if (CurrentToken() == Token::kINTERPOL_START) { | 14804 } else if (CurrentToken() == Token::kINTERPOL_START) { |
| 15128 ConsumeToken(); | 14805 ConsumeToken(); |
| 15129 const bool saved_mode = SetAllowFunctionLiterals(true); | 14806 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 15130 SkipExpr(); | 14807 SkipExpr(); |
| 15131 SetAllowFunctionLiterals(saved_mode); | 14808 SetAllowFunctionLiterals(saved_mode); |
| 15132 ExpectToken(Token::kINTERPOL_END); | 14809 ExpectToken(Token::kINTERPOL_END); |
| 15133 } else { | 14810 } else { |
| 15134 break; | 14811 break; |
| 15135 } | 14812 } |
| 15136 } | 14813 } |
| 15137 } | 14814 } |
| 15138 } | 14815 } |
| 15139 | 14816 |
| 15140 | |
| 15141 void Parser::SkipPrimary() { | 14817 void Parser::SkipPrimary() { |
| 15142 if (IsFunctionLiteral()) { | 14818 if (IsFunctionLiteral()) { |
| 15143 SkipFunctionLiteral(); | 14819 SkipFunctionLiteral(); |
| 15144 return; | 14820 return; |
| 15145 } | 14821 } |
| 15146 switch (CurrentToken()) { | 14822 switch (CurrentToken()) { |
| 15147 case Token::kTHIS: | 14823 case Token::kTHIS: |
| 15148 case Token::kSUPER: | 14824 case Token::kSUPER: |
| 15149 case Token::kNULL: | 14825 case Token::kNULL: |
| 15150 case Token::kTRUE: | 14826 case Token::kTRUE: |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15191 if (IsIdentifier()) { | 14867 if (IsIdentifier()) { |
| 15192 ConsumeToken(); // Handle pseudo-keyword identifiers. | 14868 ConsumeToken(); // Handle pseudo-keyword identifiers. |
| 15193 } else { | 14869 } else { |
| 15194 UnexpectedToken(); | 14870 UnexpectedToken(); |
| 15195 UNREACHABLE(); | 14871 UNREACHABLE(); |
| 15196 } | 14872 } |
| 15197 break; | 14873 break; |
| 15198 } | 14874 } |
| 15199 } | 14875 } |
| 15200 | 14876 |
| 15201 | |
| 15202 void Parser::SkipSelectors() { | 14877 void Parser::SkipSelectors() { |
| 15203 while (true) { | 14878 while (true) { |
| 15204 const Token::Kind current_token = CurrentToken(); | 14879 const Token::Kind current_token = CurrentToken(); |
| 15205 if (current_token == Token::kCASCADE) { | 14880 if (current_token == Token::kCASCADE) { |
| 15206 ConsumeToken(); | 14881 ConsumeToken(); |
| 15207 if (CurrentToken() == Token::kLBRACK) { | 14882 if (CurrentToken() == Token::kLBRACK) { |
| 15208 continue; // Consume [ in next loop iteration. | 14883 continue; // Consume [ in next loop iteration. |
| 15209 } else { | 14884 } else { |
| 15210 ExpectIdentifier("identifier or [ expected after .."); | 14885 ExpectIdentifier("identifier or [ expected after .."); |
| 15211 } | 14886 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 15237 } else { | 14912 } else { |
| 15238 ReportError("identifier or operator expected"); | 14913 ReportError("identifier or operator expected"); |
| 15239 } | 14914 } |
| 15240 } | 14915 } |
| 15241 SkipSelectors(); | 14916 SkipSelectors(); |
| 15242 if (IsIncrementOperator(CurrentToken())) { | 14917 if (IsIncrementOperator(CurrentToken())) { |
| 15243 ConsumeToken(); | 14918 ConsumeToken(); |
| 15244 } | 14919 } |
| 15245 } | 14920 } |
| 15246 | 14921 |
| 15247 | |
| 15248 void Parser::SkipUnaryExpr() { | 14922 void Parser::SkipUnaryExpr() { |
| 15249 if (IsPrefixOperator(CurrentToken()) || IsIncrementOperator(CurrentToken()) || | 14923 if (IsPrefixOperator(CurrentToken()) || IsIncrementOperator(CurrentToken()) || |
| 15250 IsAwaitKeyword()) { | 14924 IsAwaitKeyword()) { |
| 15251 ConsumeToken(); | 14925 ConsumeToken(); |
| 15252 SkipUnaryExpr(); | 14926 SkipUnaryExpr(); |
| 15253 } else { | 14927 } else { |
| 15254 SkipPostfixExpr(); | 14928 SkipPostfixExpr(); |
| 15255 } | 14929 } |
| 15256 } | 14930 } |
| 15257 | 14931 |
| 15258 | |
| 15259 void Parser::SkipBinaryExpr() { | 14932 void Parser::SkipBinaryExpr() { |
| 15260 SkipUnaryExpr(); | 14933 SkipUnaryExpr(); |
| 15261 const int min_prec = Token::Precedence(Token::kIFNULL); | 14934 const int min_prec = Token::Precedence(Token::kIFNULL); |
| 15262 const int max_prec = Token::Precedence(Token::kMUL); | 14935 const int max_prec = Token::Precedence(Token::kMUL); |
| 15263 while (((min_prec <= Token::Precedence(CurrentToken())) && | 14936 while (((min_prec <= Token::Precedence(CurrentToken())) && |
| 15264 (Token::Precedence(CurrentToken()) <= max_prec))) { | 14937 (Token::Precedence(CurrentToken()) <= max_prec))) { |
| 15265 if (CurrentToken() == Token::kIS) { | 14938 if (CurrentToken() == Token::kIS) { |
| 15266 ConsumeToken(); | 14939 ConsumeToken(); |
| 15267 if (CurrentToken() == Token::kNOT) { | 14940 if (CurrentToken() == Token::kNOT) { |
| 15268 ConsumeToken(); | 14941 ConsumeToken(); |
| 15269 } | 14942 } |
| 15270 SkipTypeOrFunctionType(false); | 14943 SkipTypeOrFunctionType(false); |
| 15271 } else if (CurrentToken() == Token::kAS) { | 14944 } else if (CurrentToken() == Token::kAS) { |
| 15272 ConsumeToken(); | 14945 ConsumeToken(); |
| 15273 SkipTypeOrFunctionType(false); | 14946 SkipTypeOrFunctionType(false); |
| 15274 } else { | 14947 } else { |
| 15275 ConsumeToken(); | 14948 ConsumeToken(); |
| 15276 SkipUnaryExpr(); | 14949 SkipUnaryExpr(); |
| 15277 } | 14950 } |
| 15278 } | 14951 } |
| 15279 } | 14952 } |
| 15280 | 14953 |
| 15281 | |
| 15282 void Parser::SkipConditionalExpr() { | 14954 void Parser::SkipConditionalExpr() { |
| 15283 SkipBinaryExpr(); | 14955 SkipBinaryExpr(); |
| 15284 if (CurrentToken() == Token::kCONDITIONAL) { | 14956 if (CurrentToken() == Token::kCONDITIONAL) { |
| 15285 ConsumeToken(); | 14957 ConsumeToken(); |
| 15286 SkipExpr(); | 14958 SkipExpr(); |
| 15287 ExpectToken(Token::kCOLON); | 14959 ExpectToken(Token::kCOLON); |
| 15288 SkipExpr(); | 14960 SkipExpr(); |
| 15289 } | 14961 } |
| 15290 } | 14962 } |
| 15291 | 14963 |
| 15292 | |
| 15293 void Parser::SkipExpr() { | 14964 void Parser::SkipExpr() { |
| 15294 while (CurrentToken() == Token::kTHROW) { | 14965 while (CurrentToken() == Token::kTHROW) { |
| 15295 ConsumeToken(); | 14966 ConsumeToken(); |
| 15296 } | 14967 } |
| 15297 SkipConditionalExpr(); | 14968 SkipConditionalExpr(); |
| 15298 if (CurrentToken() == Token::kCASCADE) { | 14969 if (CurrentToken() == Token::kCASCADE) { |
| 15299 SkipSelectors(); | 14970 SkipSelectors(); |
| 15300 } | 14971 } |
| 15301 if (Token::IsAssignmentOperator(CurrentToken())) { | 14972 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 15302 ConsumeToken(); | 14973 ConsumeToken(); |
| 15303 SkipExpr(); | 14974 SkipExpr(); |
| 15304 } | 14975 } |
| 15305 } | 14976 } |
| 15306 | 14977 |
| 15307 | |
| 15308 void Parser::SkipNestedExpr() { | 14978 void Parser::SkipNestedExpr() { |
| 15309 const bool saved_mode = SetAllowFunctionLiterals(true); | 14979 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 15310 SkipExpr(); | 14980 SkipExpr(); |
| 15311 SetAllowFunctionLiterals(saved_mode); | 14981 SetAllowFunctionLiterals(saved_mode); |
| 15312 } | 14982 } |
| 15313 | 14983 |
| 15314 | |
| 15315 void Parser::SkipQualIdent() { | 14984 void Parser::SkipQualIdent() { |
| 15316 ASSERT(IsIdentifier()); | 14985 ASSERT(IsIdentifier()); |
| 15317 ConsumeToken(); | 14986 ConsumeToken(); |
| 15318 if (CurrentToken() == Token::kPERIOD) { | 14987 if (CurrentToken() == Token::kPERIOD) { |
| 15319 ConsumeToken(); // Consume the kPERIOD token. | 14988 ConsumeToken(); // Consume the kPERIOD token. |
| 15320 ExpectIdentifier("identifier expected after '.'"); | 14989 ExpectIdentifier("identifier expected after '.'"); |
| 15321 } | 14990 } |
| 15322 } | 14991 } |
| 15323 | 14992 |
| 15324 } // namespace dart | 14993 } // namespace dart |
| 15325 | 14994 |
| 15326 | |
| 15327 #else // DART_PRECOMPILED_RUNTIME | 14995 #else // DART_PRECOMPILED_RUNTIME |
| 15328 | 14996 |
| 15329 | |
| 15330 namespace dart { | 14997 namespace dart { |
| 15331 | 14998 |
| 15332 void ParsedFunction::AddToGuardedFields(const Field* field) const { | 14999 void ParsedFunction::AddToGuardedFields(const Field* field) const { |
| 15333 UNREACHABLE(); | 15000 UNREACHABLE(); |
| 15334 } | 15001 } |
| 15335 | 15002 |
| 15336 | |
| 15337 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { | 15003 kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() { |
| 15338 UNREACHABLE(); | 15004 UNREACHABLE(); |
| 15339 return NULL; | 15005 return NULL; |
| 15340 } | 15006 } |
| 15341 | 15007 |
| 15342 | |
| 15343 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 15008 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
| 15344 UNREACHABLE(); | 15009 UNREACHABLE(); |
| 15345 return NULL; | 15010 return NULL; |
| 15346 } | 15011 } |
| 15347 | 15012 |
| 15348 | |
| 15349 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 15013 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 15350 UNREACHABLE(); | 15014 UNREACHABLE(); |
| 15351 } | 15015 } |
| 15352 | 15016 |
| 15353 | |
| 15354 void ParsedFunction::SetRegExpCompileData( | 15017 void ParsedFunction::SetRegExpCompileData( |
| 15355 RegExpCompileData* regexp_compile_data) { | 15018 RegExpCompileData* regexp_compile_data) { |
| 15356 UNREACHABLE(); | 15019 UNREACHABLE(); |
| 15357 } | 15020 } |
| 15358 | 15021 |
| 15359 | |
| 15360 void ParsedFunction::AllocateVariables() { | 15022 void ParsedFunction::AllocateVariables() { |
| 15361 UNREACHABLE(); | 15023 UNREACHABLE(); |
| 15362 } | 15024 } |
| 15363 | 15025 |
| 15364 | |
| 15365 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 15026 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
| 15366 UNREACHABLE(); | 15027 UNREACHABLE(); |
| 15367 } | 15028 } |
| 15368 | 15029 |
| 15369 | |
| 15370 void ParsedFunction::Bailout(const char* origin, const char* reason) const { | 15030 void ParsedFunction::Bailout(const char* origin, const char* reason) const { |
| 15371 UNREACHABLE(); | 15031 UNREACHABLE(); |
| 15372 } | 15032 } |
| 15373 | 15033 |
| 15374 | |
| 15375 void Parser::ParseCompilationUnit(const Library& library, | 15034 void Parser::ParseCompilationUnit(const Library& library, |
| 15376 const Script& script) { | 15035 const Script& script) { |
| 15377 UNREACHABLE(); | 15036 UNREACHABLE(); |
| 15378 } | 15037 } |
| 15379 | 15038 |
| 15380 | |
| 15381 void Parser::ParseClass(const Class& cls) { | 15039 void Parser::ParseClass(const Class& cls) { |
| 15382 UNREACHABLE(); | 15040 UNREACHABLE(); |
| 15383 } | 15041 } |
| 15384 | 15042 |
| 15385 | |
| 15386 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 15043 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
| 15387 UNREACHABLE(); | 15044 UNREACHABLE(); |
| 15388 return Object::null(); | 15045 return Object::null(); |
| 15389 } | 15046 } |
| 15390 | 15047 |
| 15391 | |
| 15392 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 15048 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 15393 UNREACHABLE(); | 15049 UNREACHABLE(); |
| 15394 } | 15050 } |
| 15395 | 15051 |
| 15396 | |
| 15397 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 15052 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
| 15398 UNREACHABLE(); | 15053 UNREACHABLE(); |
| 15399 return Object::null(); | 15054 return Object::null(); |
| 15400 } | 15055 } |
| 15401 | 15056 |
| 15402 | |
| 15403 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 15057 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
| 15404 UNREACHABLE(); | 15058 UNREACHABLE(); |
| 15405 return NULL; | 15059 return NULL; |
| 15406 } | 15060 } |
| 15407 | 15061 |
| 15408 | |
| 15409 void Parser::InsertCachedConstantValue(const Script& script, | 15062 void Parser::InsertCachedConstantValue(const Script& script, |
| 15410 TokenPosition token_pos, | 15063 TokenPosition token_pos, |
| 15411 const Instance& value) { | 15064 const Instance& value) { |
| 15412 UNREACHABLE(); | 15065 UNREACHABLE(); |
| 15413 } | 15066 } |
| 15414 | 15067 |
| 15415 | |
| 15416 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 15068 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
| 15417 TokenPosition call_pos, | 15069 TokenPosition call_pos, |
| 15418 const String& function_name, | 15070 const String& function_name, |
| 15419 const ArgumentListNode& function_args, | 15071 const ArgumentListNode& function_args, |
| 15420 const LocalVariable* temp_for_last_arg, | 15072 const LocalVariable* temp_for_last_arg, |
| 15421 bool is_super_invocation) { | 15073 bool is_super_invocation) { |
| 15422 UNREACHABLE(); | 15074 UNREACHABLE(); |
| 15423 return NULL; | 15075 return NULL; |
| 15424 } | 15076 } |
| 15425 | 15077 |
| 15426 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, | 15078 bool Parser::FieldHasFunctionLiteralInitializer(const Field& field, |
| 15427 TokenPosition* start, | 15079 TokenPosition* start, |
| 15428 TokenPosition* end) { | 15080 TokenPosition* end) { |
| 15429 UNREACHABLE(); | 15081 UNREACHABLE(); |
| 15430 return false; | 15082 return false; |
| 15431 } | 15083 } |
| 15432 | 15084 |
| 15433 | |
| 15434 } // namespace dart | 15085 } // namespace dart |
| 15435 | 15086 |
| 15436 #endif // DART_PRECOMPILED_RUNTIME | 15087 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |