Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 73 private: | 73 private: |
| 74 void PrintIndent() { | 74 void PrintIndent() { |
| 75 for (int i = 0; i < indent_; i++) { OS::Print(". "); } | 75 for (int i = 0; i < indent_; i++) { OS::Print(". "); } |
| 76 } | 76 } |
| 77 static int indent_; | 77 static int indent_; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 int TraceParser::indent_ = 0; | 80 int TraceParser::indent_ = 0; |
| 81 | 81 |
| 82 #define TRACE_PARSER(s) \ | 82 #define TRACE_PARSER(s) \ |
| 83 TraceParser __p__(this->token_index_, this->script_, s) | 83 TraceParser __p__(this->TokenIndex(), this->script_, s) |
| 84 | 84 |
| 85 #else // not DEBUG | 85 #else // not DEBUG |
| 86 #define TRACE_PARSER(s) | 86 #define TRACE_PARSER(s) |
| 87 #endif // DEBUG | 87 #endif // DEBUG |
| 88 | 88 |
| 89 | 89 |
| 90 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { | 90 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { |
| 91 const TypeArguments& a = | 91 const TypeArguments& a = |
| 92 TypeArguments::Handle(TypeArguments::New(objs.Length())); | 92 TypeArguments::Handle(TypeArguments::New(objs.Length())); |
| 93 AbstractType& type = AbstractType::Handle(); | 93 AbstractType& type = AbstractType::Handle(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 scope->AddVariable(context_var); | 189 scope->AddVariable(context_var); |
| 190 set_saved_context_var(context_var); | 190 set_saved_context_var(context_var); |
| 191 } | 191 } |
| 192 | 192 |
| 193 // Frame indices are relative to the frame pointer and are decreasing. | 193 // Frame indices are relative to the frame pointer and are decreasing. |
| 194 ASSERT(next_free_frame_index <= first_stack_local_index_); | 194 ASSERT(next_free_frame_index <= first_stack_local_index_); |
| 195 stack_local_count_ = first_stack_local_index_ - next_free_frame_index; | 195 stack_local_count_ = first_stack_local_index_ - next_free_frame_index; |
| 196 } | 196 } |
| 197 | 197 |
| 198 | 198 |
| 199 bool TokenStreamIterator::IsNull() const { | |
| 200 return tokens_.IsNull(); | |
| 201 } | |
| 202 | |
| 203 | |
| 204 Token::Kind TokenStreamIterator::CurrentTokenKind() const { | |
| 205 return tokens_.KindAt(token_index_); | |
| 206 } | |
| 207 | |
| 208 | |
| 209 Token::Kind TokenStreamIterator::LookaheadTokenKind(intptr_t num_tokens) const { | |
| 210 return tokens_.KindAt(token_index_ + num_tokens); | |
| 211 } | |
| 212 | |
| 213 | |
| 214 RawObject* TokenStreamIterator::CurrentToken() const { | |
| 215 return tokens_.TokenAt(token_index_); | |
| 216 } | |
| 217 | |
| 218 | |
| 219 RawString* TokenStreamIterator::CurrentLiteral() const { | |
| 220 return tokens_.LiteralAt(token_index_); | |
| 221 } | |
| 222 | |
| 223 | |
| 199 struct Parser::Block : public ZoneAllocated { | 224 struct Parser::Block : public ZoneAllocated { |
| 200 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) | 225 Block(Block* outer_block, LocalScope* local_scope, SequenceNode* seq) |
| 201 : parent(outer_block), scope(local_scope), statements(seq) { | 226 : parent(outer_block), scope(local_scope), statements(seq) { |
| 202 ASSERT(scope != NULL); | 227 ASSERT(scope != NULL); |
| 203 ASSERT(statements != NULL); | 228 ASSERT(statements != NULL); |
| 204 } | 229 } |
| 205 Block* parent; // Enclosing block, or NULL if outermost. | 230 Block* parent; // Enclosing block, or NULL if outermost. |
| 206 LocalScope* scope; | 231 LocalScope* scope; |
| 207 SequenceNode* statements; | 232 SequenceNode* statements; |
| 208 }; | 233 }; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 | 265 |
| 241 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { | 266 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { |
| 242 inlined_finally_nodes_.Add(node); | 267 inlined_finally_nodes_.Add(node); |
| 243 } | 268 } |
| 244 | 269 |
| 245 | 270 |
| 246 // For parsing a compilation unit. | 271 // For parsing a compilation unit. |
| 247 Parser::Parser(const Script& script, | 272 Parser::Parser(const Script& script, |
| 248 const Library& library) | 273 const Library& library) |
| 249 : script_(script), | 274 : script_(script), |
| 250 tokens_(TokenStream::Handle(script.tokens())), | 275 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), |
| 251 token_index_(0), | 276 token_kind_(Token::kILLEGAL), |
| 252 current_block_(NULL), | 277 current_block_(NULL), |
| 253 is_top_level_(false), | 278 is_top_level_(false), |
| 254 current_member_(NULL), | 279 current_member_(NULL), |
| 255 allow_function_literals_(true), | 280 allow_function_literals_(true), |
| 256 current_function_(Function::Handle()), | 281 current_function_(Function::Handle()), |
| 257 current_class_(Class::Handle()), | 282 current_class_(Class::Handle()), |
| 258 library_(library), | 283 library_(library), |
| 259 try_blocks_list_(NULL), | 284 try_blocks_list_(NULL), |
| 260 expression_temp_(NULL) { | 285 expression_temp_(NULL) { |
| 261 ASSERT(!tokens_.IsNull()); | 286 ASSERT(!tokens_iterator_.IsNull()); |
| 262 ASSERT(!library.IsNull()); | 287 ASSERT(!library.IsNull()); |
| 263 SetPosition(0); | |
| 264 } | 288 } |
| 265 | 289 |
| 266 | 290 |
| 267 // For parsing a function. | 291 // For parsing a function. |
| 268 Parser::Parser(const Script& script, | 292 Parser::Parser(const Script& script, |
| 269 const Function& function, | 293 const Function& function, |
| 270 intptr_t token_index) | 294 intptr_t token_index) |
| 271 : script_(script), | 295 : script_(script), |
| 272 tokens_(TokenStream::Handle(script.tokens())), | 296 tokens_iterator_(TokenStream::Handle(script.tokens()), token_index), |
| 273 token_index_(0), | 297 token_kind_(Token::kILLEGAL), |
| 274 current_block_(NULL), | 298 current_block_(NULL), |
| 275 is_top_level_(false), | 299 is_top_level_(false), |
| 276 current_member_(NULL), | 300 current_member_(NULL), |
| 277 allow_function_literals_(true), | 301 allow_function_literals_(true), |
| 278 current_function_(function), | 302 current_function_(function), |
| 279 current_class_(Class::Handle(current_function_.owner())), | 303 current_class_(Class::Handle(current_function_.owner())), |
| 280 library_(Library::Handle(current_class_.library())), | 304 library_(Library::Handle(current_class_.library())), |
| 281 try_blocks_list_(NULL), | 305 try_blocks_list_(NULL), |
| 282 expression_temp_(NULL) { | 306 expression_temp_(NULL) { |
| 283 ASSERT(!tokens_.IsNull()); | 307 ASSERT(!tokens_iterator_.IsNull()); |
| 284 ASSERT(!function.IsNull()); | 308 ASSERT(!function.IsNull()); |
| 285 SetPosition(token_index); | |
| 286 if (FLAG_enable_type_checks) { | 309 if (FLAG_enable_type_checks) { |
| 287 EnsureExpressionTemp(); | 310 EnsureExpressionTemp(); |
| 288 } | 311 } |
| 289 } | 312 } |
| 290 | 313 |
| 291 | 314 |
| 292 bool Parser::SetAllowFunctionLiterals(bool value) { | 315 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 293 bool current_value = allow_function_literals_; | 316 bool current_value = allow_function_literals_; |
| 294 allow_function_literals_ = value; | 317 allow_function_literals_ = value; |
| 295 return current_value; | 318 return current_value; |
| 296 } | 319 } |
| 297 | 320 |
| 298 | 321 |
| 299 const Function& Parser::current_function() const { | 322 const Function& Parser::current_function() const { |
| 300 return current_function_; | 323 return current_function_; |
| 301 } | 324 } |
| 302 | 325 |
| 303 | 326 |
| 304 const Class& Parser::current_class() const { | 327 const Class& Parser::current_class() const { |
| 305 return current_class_; | 328 return current_class_; |
| 306 } | 329 } |
| 307 | 330 |
| 308 | 331 |
| 309 void Parser::set_current_class(const Class& value) { | 332 void Parser::set_current_class(const Class& value) { |
| 310 current_class_ = value.raw(); | 333 current_class_ = value.raw(); |
| 311 } | 334 } |
| 312 | 335 |
| 313 | 336 |
| 314 void Parser::SetPosition(intptr_t position) { | 337 void Parser::SetPosition(intptr_t position) { |
| 315 if (position < token_index_ && position != 0) { | 338 if (position < TokenIndex() && position != 0) { |
| 316 CompilerStats::num_tokens_rewind += (token_index_ - position); | 339 CompilerStats::num_tokens_rewind += (TokenIndex() - position); |
| 317 } | 340 } |
| 318 token_index_ = position; | 341 tokens_iterator_.SetCurrentIndex(position); |
| 319 token_kind_ = Token::kILLEGAL; | 342 token_kind_ = Token::kILLEGAL; |
| 320 } | 343 } |
| 321 | 344 |
| 322 | 345 |
| 323 void Parser::ParseCompilationUnit(const Library& library, | 346 void Parser::ParseCompilationUnit(const Library& library, |
| 324 const Script& script) { | 347 const Script& script) { |
| 325 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); | 348 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); |
| 326 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 349 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 327 Parser parser(script, library); | 350 Parser parser(script, library); |
| 328 parser.ParseTopLevel(); | 351 parser.ParseTopLevel(); |
| 329 if (FLAG_compiler_stats) { | 352 if (FLAG_compiler_stats) { |
| 330 CompilerStats::num_tokens_total += parser.tokens_.Length(); | 353 CompilerStats::num_tokens_total += parser.tokens_iterator_.Length(); |
|
hausner
2012/06/22 00:02:27
The number of tokens will not be equivalent to the
siva
2012/06/22 17:59:02
Changed name Length() to NumberOfTokens() in the s
| |
| 331 } | 354 } |
| 332 } | 355 } |
| 333 | 356 |
| 334 | 357 |
| 335 Token::Kind Parser::CurrentToken() { | 358 Token::Kind Parser::CurrentToken() { |
| 336 if (token_kind_ == Token::kILLEGAL) { | 359 if (token_kind_ == Token::kILLEGAL) { |
| 337 token_kind_ = tokens_.KindAt(token_index_); | 360 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 338 if (token_kind_ == Token::kERROR) { | 361 if (token_kind_ == Token::kERROR) { |
| 339 ErrorMsg(token_index_, CurrentLiteral()->ToCString()); | 362 ErrorMsg(TokenIndex(), CurrentLiteral()->ToCString()); |
| 340 } | 363 } |
| 341 } | 364 } |
| 342 CompilerStats::num_token_checks++; | 365 CompilerStats::num_token_checks++; |
| 343 return token_kind_; | 366 return token_kind_; |
| 344 } | 367 } |
| 345 | 368 |
| 346 | 369 |
| 347 Token::Kind Parser::LookaheadToken(int num_tokens) { | 370 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| 348 CompilerStats::num_tokens_lookahead++; | 371 CompilerStats::num_tokens_lookahead++; |
| 349 CompilerStats::num_token_checks++; | 372 CompilerStats::num_token_checks++; |
| 350 return tokens_.KindAt(token_index_ + num_tokens); | 373 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
| 351 } | 374 } |
| 352 | 375 |
| 353 | 376 |
| 354 String* Parser::CurrentLiteral() const { | 377 String* Parser::CurrentLiteral() const { |
| 355 String& result = String::ZoneHandle(); | 378 String& result = String::ZoneHandle(); |
| 356 result ^= tokens_.LiteralAt(token_index_); | 379 result ^= tokens_iterator_.CurrentLiteral(); |
| 357 return &result; | 380 return &result; |
| 358 } | 381 } |
| 359 | 382 |
| 360 | 383 |
| 361 RawDouble* Parser::CurrentDoubleLiteral() const { | 384 RawDouble* Parser::CurrentDoubleLiteral() const { |
| 362 LiteralToken& token = LiteralToken::Handle(); | 385 LiteralToken& token = LiteralToken::Handle(); |
| 363 token ^= tokens_.TokenAt(token_index_); | 386 token ^= tokens_iterator_.CurrentToken(); |
| 364 ASSERT(token.kind() == Token::kDOUBLE); | 387 ASSERT(token.kind() == Token::kDOUBLE); |
| 365 return reinterpret_cast<RawDouble*>(token.value()); | 388 return reinterpret_cast<RawDouble*>(token.value()); |
| 366 } | 389 } |
| 367 | 390 |
| 368 | 391 |
| 369 RawInteger* Parser::CurrentIntegerLiteral() const { | 392 RawInteger* Parser::CurrentIntegerLiteral() const { |
| 370 LiteralToken& token = LiteralToken::Handle(); | 393 LiteralToken& token = LiteralToken::Handle(); |
| 371 token ^= tokens_.TokenAt(token_index_); | 394 token ^= tokens_iterator_.CurrentToken(); |
| 372 ASSERT(token.kind() == Token::kINTEGER); | 395 ASSERT(token.kind() == Token::kINTEGER); |
| 373 return reinterpret_cast<RawInteger*>(token.value()); | 396 return reinterpret_cast<RawInteger*>(token.value()); |
| 374 } | 397 } |
| 375 | 398 |
| 376 | 399 |
| 377 // A QualIdent is an optionally qualified identifier. | 400 // A QualIdent is an optionally qualified identifier. |
| 378 struct QualIdent { | 401 struct QualIdent { |
| 379 QualIdent() { | 402 QualIdent() { |
| 380 Clear(); | 403 Clear(); |
| 381 } | 404 } |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 break; | 720 break; |
| 698 case RawFunction::kConstImplicitGetter: | 721 case RawFunction::kConstImplicitGetter: |
| 699 node_sequence = parser.ParseStaticConstGetter(func); | 722 node_sequence = parser.ParseStaticConstGetter(func); |
| 700 break; | 723 break; |
| 701 default: | 724 default: |
| 702 UNREACHABLE(); | 725 UNREACHABLE(); |
| 703 } | 726 } |
| 704 | 727 |
| 705 if (!HasReturnNode(node_sequence)) { | 728 if (!HasReturnNode(node_sequence)) { |
| 706 // Add implicit return node. | 729 // Add implicit return node. |
| 707 node_sequence->Add(new ReturnNode(parser.token_index_)); | 730 node_sequence->Add(new ReturnNode(parser.TokenIndex())); |
| 708 } | 731 } |
| 709 if (parser.expression_temp_ != NULL) { | 732 if (parser.expression_temp_ != NULL) { |
| 710 parsed_function->set_expression_temp_var(parser.expression_temp_); | 733 parsed_function->set_expression_temp_var(parser.expression_temp_); |
| 711 } | 734 } |
| 712 if (parsed_function->has_expression_temp_var()) { | 735 if (parsed_function->has_expression_temp_var()) { |
| 713 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 736 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 714 } | 737 } |
| 715 parsed_function->SetNodeSequence(node_sequence); | 738 parsed_function->SetNodeSequence(node_sequence); |
| 716 | 739 |
| 717 // The instantiator may be required at run time for generic type checks or | 740 // The instantiator may be required at run time for generic type checks or |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 757 Field::ZoneHandle(field_class.LookupStaticField(field_name)); | 780 Field::ZoneHandle(field_class.LookupStaticField(field_name)); |
| 758 | 781 |
| 759 // Static const fields must have an initializer. | 782 // Static const fields must have an initializer. |
| 760 ExpectToken(Token::kASSIGN); | 783 ExpectToken(Token::kASSIGN); |
| 761 | 784 |
| 762 // We don't want to use ParseConstExpr() here because we don't want | 785 // We don't want to use ParseConstExpr() here because we don't want |
| 763 // the constant folding code to create, compile and execute a code | 786 // the constant folding code to create, compile and execute a code |
| 764 // fragment to evaluate the expression. Instead, we just make sure | 787 // fragment to evaluate the expression. Instead, we just make sure |
| 765 // the static const field initializer is a constant expression and | 788 // the static const field initializer is a constant expression and |
| 766 // leave the evaluation to the getter function. | 789 // leave the evaluation to the getter function. |
| 767 const intptr_t expr_pos = token_index_; | 790 const intptr_t expr_pos = TokenIndex(); |
| 768 AstNode* expr = ParseExpr(kAllowConst); | 791 AstNode* expr = ParseExpr(kAllowConst); |
| 769 if (field.is_const()) { | 792 if (field.is_const()) { |
| 770 // This getter will only be called once at compile time. | 793 // This getter will only be called once at compile time. |
| 771 if (expr->EvalConstExpr() == NULL) { | 794 if (expr->EvalConstExpr() == NULL) { |
| 772 ErrorMsg(expr_pos, "initializer must be a compile time constant"); | 795 ErrorMsg(expr_pos, "initializer must be a compile time constant"); |
| 773 } | 796 } |
| 774 ReturnNode* return_node = new ReturnNode(token_index_, expr); | 797 ReturnNode* return_node = new ReturnNode(TokenIndex(), expr); |
| 775 current_block_->statements->Add(return_node); | 798 current_block_->statements->Add(return_node); |
| 776 } else { | 799 } else { |
| 777 // This getter may be called each time the static field is accessed. | 800 // This getter may be called each time the static field is accessed. |
| 778 // The following generated code lazily initializes the field: | 801 // The following generated code lazily initializes the field: |
| 779 // if (field.value === transition_sentinel) { | 802 // if (field.value === transition_sentinel) { |
| 780 // field.value = null; | 803 // field.value = null; |
| 781 // throw("circular dependency in field initialization"); | 804 // throw("circular dependency in field initialization"); |
| 782 // } | 805 // } |
| 783 // if (field.value === sentinel) { | 806 // if (field.value === sentinel) { |
| 784 // field.value = transition_sentinel; | 807 // field.value = transition_sentinel; |
| 785 // field.value = expr; | 808 // field.value = expr; |
| 786 // } | 809 // } |
| 787 // return field.value; // Type check is executed here in checked mode. | 810 // return field.value; // Type check is executed here in checked mode. |
| 788 | 811 |
| 789 // TODO(regis): Remove this check once we support proper const fields. | 812 // TODO(regis): Remove this check once we support proper const fields. |
| 790 if (expr->EvalConstExpr() == NULL) { | 813 if (expr->EvalConstExpr() == NULL) { |
| 791 ErrorMsg(expr_pos, "initializer must be a compile time constant"); | 814 ErrorMsg(expr_pos, "initializer must be a compile time constant"); |
| 792 } | 815 } |
| 793 | 816 |
| 794 // Generate code checking for circular dependency in field initialization. | 817 // Generate code checking for circular dependency in field initialization. |
| 795 AstNode* compare_circular = new ComparisonNode( | 818 AstNode* compare_circular = new ComparisonNode( |
| 796 token_index_, | 819 TokenIndex(), |
| 797 Token::kEQ_STRICT, | 820 Token::kEQ_STRICT, |
| 798 new LoadStaticFieldNode(token_index_, field), | 821 new LoadStaticFieldNode(TokenIndex(), field), |
| 799 new LiteralNode(token_index_, | 822 new LiteralNode(TokenIndex(), |
| 800 Instance::ZoneHandle(Object::transition_sentinel()))); | 823 Instance::ZoneHandle(Object::transition_sentinel()))); |
| 801 // Set field to null prior to throwing exception, so that subsequent | 824 // Set field to null prior to throwing exception, so that subsequent |
| 802 // accesses to the field do not throw again, since initializers should only | 825 // accesses to the field do not throw again, since initializers should only |
| 803 // be executed once. | 826 // be executed once. |
| 804 SequenceNode* report_circular = new SequenceNode(token_index_, NULL); | 827 SequenceNode* report_circular = new SequenceNode(TokenIndex(), NULL); |
| 805 report_circular->Add( | 828 report_circular->Add( |
| 806 new StoreStaticFieldNode( | 829 new StoreStaticFieldNode( |
| 807 token_index_, | 830 TokenIndex(), |
| 808 field, | 831 field, |
| 809 new LiteralNode(token_index_, Instance::ZoneHandle()))); | 832 new LiteralNode(TokenIndex(), Instance::ZoneHandle()))); |
| 810 // TODO(regis): Exception to throw is not specified by spec. | 833 // TODO(regis): Exception to throw is not specified by spec. |
| 811 const String& circular_error = String::ZoneHandle( | 834 const String& circular_error = String::ZoneHandle( |
| 812 String::NewSymbol("circular dependency in field initialization")); | 835 String::NewSymbol("circular dependency in field initialization")); |
| 813 report_circular->Add( | 836 report_circular->Add( |
| 814 new ThrowNode(token_index_, | 837 new ThrowNode(TokenIndex(), |
| 815 new LiteralNode(token_index_, circular_error), | 838 new LiteralNode(TokenIndex(), circular_error), |
| 816 NULL)); | 839 NULL)); |
| 817 AstNode* circular_check = | 840 AstNode* circular_check = |
| 818 new IfNode(token_index_, compare_circular, report_circular, NULL); | 841 new IfNode(TokenIndex(), compare_circular, report_circular, NULL); |
| 819 current_block_->statements->Add(circular_check); | 842 current_block_->statements->Add(circular_check); |
| 820 | 843 |
| 821 // Generate code checking for uninitialized field. | 844 // Generate code checking for uninitialized field. |
| 822 AstNode* compare_uninitialized = new ComparisonNode( | 845 AstNode* compare_uninitialized = new ComparisonNode( |
| 823 token_index_, | 846 TokenIndex(), |
| 824 Token::kEQ_STRICT, | 847 Token::kEQ_STRICT, |
| 825 new LoadStaticFieldNode(token_index_, field), | 848 new LoadStaticFieldNode(TokenIndex(), field), |
| 826 new LiteralNode(token_index_, | 849 new LiteralNode(TokenIndex(), |
| 827 Instance::ZoneHandle(Object::sentinel()))); | 850 Instance::ZoneHandle(Object::sentinel()))); |
| 828 SequenceNode* initialize_field = new SequenceNode(token_index_, NULL); | 851 SequenceNode* initialize_field = new SequenceNode(TokenIndex(), NULL); |
| 829 initialize_field->Add( | 852 initialize_field->Add( |
| 830 new StoreStaticFieldNode( | 853 new StoreStaticFieldNode( |
| 831 token_index_, | 854 TokenIndex(), |
| 832 field, | 855 field, |
| 833 new LiteralNode( | 856 new LiteralNode( |
| 834 token_index_, | 857 TokenIndex(), |
| 835 Instance::ZoneHandle(Object::transition_sentinel())))); | 858 Instance::ZoneHandle(Object::transition_sentinel())))); |
| 836 initialize_field->Add(new StoreStaticFieldNode(token_index_, field, expr)); | 859 initialize_field->Add(new StoreStaticFieldNode(TokenIndex(), field, expr)); |
| 837 AstNode* uninitialized_check = | 860 AstNode* uninitialized_check = |
| 838 new IfNode(token_index_, compare_uninitialized, initialize_field, NULL); | 861 new IfNode(TokenIndex(), compare_uninitialized, initialize_field, NULL); |
| 839 current_block_->statements->Add(uninitialized_check); | 862 current_block_->statements->Add(uninitialized_check); |
| 840 | 863 |
| 841 // Generate code returning the field value. | 864 // Generate code returning the field value. |
| 842 ReturnNode* return_node = | 865 ReturnNode* return_node = |
| 843 new ReturnNode(token_index_, | 866 new ReturnNode(TokenIndex(), |
| 844 new LoadStaticFieldNode(token_index_, field)); | 867 new LoadStaticFieldNode(TokenIndex(), field)); |
| 845 current_block_->statements->Add(return_node); | 868 current_block_->statements->Add(return_node); |
| 846 } | 869 } |
| 847 return CloseBlock(); | 870 return CloseBlock(); |
| 848 } | 871 } |
| 849 | 872 |
| 850 | 873 |
| 851 // Create AstNodes for an implicit instance getter method: | 874 // Create AstNodes for an implicit instance getter method: |
| 852 // LoadLocalNode 0 ('this'); | 875 // LoadLocalNode 0 ('this'); |
| 853 // LoadInstanceFieldNode (field_name); | 876 // LoadInstanceFieldNode (field_name); |
| 854 // ReturnNode (field's value); | 877 // ReturnNode (field's value); |
| 855 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 878 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 856 TRACE_PARSER("ParseInstanceGetter"); | 879 TRACE_PARSER("ParseInstanceGetter"); |
| 857 ParamList params; | 880 ParamList params; |
| 858 params.AddReceiver(token_index_); | 881 params.AddReceiver(TokenIndex()); |
| 859 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 882 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
| 860 ASSERT(func.num_optional_parameters() == 0); | 883 ASSERT(func.num_optional_parameters() == 0); |
| 861 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 884 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 862 | 885 |
| 863 // Build local scope for function and populate with the formal parameters. | 886 // Build local scope for function and populate with the formal parameters. |
| 864 OpenFunctionBlock(func); | 887 OpenFunctionBlock(func); |
| 865 AddFormalParamsToScope(¶ms, current_block_->scope); | 888 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 866 | 889 |
| 867 // Receiver is local 0. | 890 // Receiver is local 0. |
| 868 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 891 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 869 LoadLocalNode* load_receiver = new LoadLocalNode(token_index_, *receiver); | 892 LoadLocalNode* load_receiver = new LoadLocalNode(TokenIndex(), *receiver); |
| 870 // token_index_ is the function's token position which points to the name of | 893 // TokenIndex() returns the function's token position which points to the |
| 871 // the field; | 894 // name of the field; |
| 872 ASSERT(IsIdentifier()); | 895 ASSERT(IsIdentifier()); |
| 873 const String& field_name = *CurrentLiteral(); | 896 const String& field_name = *CurrentLiteral(); |
| 874 const Class& field_class = Class::Handle(func.owner()); | 897 const Class& field_class = Class::Handle(func.owner()); |
| 875 const Field& field = | 898 const Field& field = |
| 876 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 899 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
| 877 | 900 |
| 878 LoadInstanceFieldNode* load_field = | 901 LoadInstanceFieldNode* load_field = |
| 879 new LoadInstanceFieldNode(token_index_, load_receiver, field); | 902 new LoadInstanceFieldNode(TokenIndex(), load_receiver, field); |
| 880 | 903 |
| 881 ReturnNode* return_node = new ReturnNode(token_index_, load_field); | 904 ReturnNode* return_node = new ReturnNode(TokenIndex(), load_field); |
| 882 current_block_->statements->Add(return_node); | 905 current_block_->statements->Add(return_node); |
| 883 return CloseBlock(); | 906 return CloseBlock(); |
| 884 } | 907 } |
| 885 | 908 |
| 886 | 909 |
| 887 // Create AstNodes for an implicit instance setter method: | 910 // Create AstNodes for an implicit instance setter method: |
| 888 // LoadLocalNode 0 ('this') | 911 // LoadLocalNode 0 ('this') |
| 889 // LoadLocalNode 1 ('value') | 912 // LoadLocalNode 1 ('value') |
| 890 // SetInstanceField (field_name); | 913 // SetInstanceField (field_name); |
| 891 // ReturnNode (void); | 914 // ReturnNode (void); |
| 892 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 915 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
| 893 TRACE_PARSER("ParseInstanceSetter"); | 916 TRACE_PARSER("ParseInstanceSetter"); |
| 894 // token_index_ is the function's token position which points to the name of | 917 // TokenIndex() returns the function's token position which points to |
| 895 // the field; we can use it to form the field_name. | 918 // the name of the field; we can use it to form the field_name. |
| 896 const String& field_name = *CurrentLiteral(); | 919 const String& field_name = *CurrentLiteral(); |
| 897 const Class& field_class = Class::ZoneHandle(func.owner()); | 920 const Class& field_class = Class::ZoneHandle(func.owner()); |
| 898 const Field& field = | 921 const Field& field = |
| 899 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 922 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
| 900 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); | 923 const AbstractType& field_type = AbstractType::ZoneHandle(field.type()); |
| 901 | 924 |
| 902 ParamList params; | 925 ParamList params; |
| 903 params.AddReceiver(token_index_); | 926 params.AddReceiver(TokenIndex()); |
| 904 params.AddFinalParameter(token_index_, "value", &field_type); | 927 params.AddFinalParameter(TokenIndex(), "value", &field_type); |
| 905 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. | 928 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. |
| 906 ASSERT(func.num_optional_parameters() == 0); | 929 ASSERT(func.num_optional_parameters() == 0); |
| 907 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); | 930 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); |
| 908 | 931 |
| 909 // Build local scope for function and populate with the formal parameters. | 932 // Build local scope for function and populate with the formal parameters. |
| 910 OpenFunctionBlock(func); | 933 OpenFunctionBlock(func); |
| 911 AddFormalParamsToScope(¶ms, current_block_->scope); | 934 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 912 | 935 |
| 913 LoadLocalNode* receiver = | 936 LoadLocalNode* receiver = |
| 914 new LoadLocalNode(token_index_, *current_block_->scope->VariableAt(0)); | 937 new LoadLocalNode(TokenIndex(), *current_block_->scope->VariableAt(0)); |
| 915 LoadLocalNode* value = | 938 LoadLocalNode* value = |
| 916 new LoadLocalNode(token_index_, *current_block_->scope->VariableAt(1)); | 939 new LoadLocalNode(TokenIndex(), *current_block_->scope->VariableAt(1)); |
| 917 | 940 |
| 918 StoreInstanceFieldNode* store_field = | 941 StoreInstanceFieldNode* store_field = |
| 919 new StoreInstanceFieldNode(token_index_, receiver, field, value); | 942 new StoreInstanceFieldNode(TokenIndex(), receiver, field, value); |
| 920 | 943 |
| 921 current_block_->statements->Add(store_field); | 944 current_block_->statements->Add(store_field); |
| 922 current_block_->statements->Add(new ReturnNode(token_index_)); | 945 current_block_->statements->Add(new ReturnNode(TokenIndex())); |
| 923 return CloseBlock(); | 946 return CloseBlock(); |
| 924 } | 947 } |
| 925 | 948 |
| 926 | 949 |
| 927 void Parser::SkipBlock() { | 950 void Parser::SkipBlock() { |
| 928 ASSERT(CurrentToken() == Token::kLBRACE); | 951 ASSERT(CurrentToken() == Token::kLBRACE); |
| 929 GrowableArray<Token::Kind> token_stack(8); | 952 GrowableArray<Token::Kind> token_stack(8); |
| 930 const intptr_t block_start_pos = token_index_; | 953 const intptr_t block_start_pos = TokenIndex(); |
| 931 bool is_match = true; | 954 bool is_match = true; |
| 932 bool unexpected_token_found = false; | 955 bool unexpected_token_found = false; |
| 933 Token::Kind token; | 956 Token::Kind token; |
| 934 intptr_t token_index; | 957 intptr_t token_index; |
| 935 do { | 958 do { |
| 936 token = CurrentToken(); | 959 token = CurrentToken(); |
| 937 token_index = token_index_; | 960 token_index = TokenIndex(); |
| 938 switch (token) { | 961 switch (token) { |
| 939 case Token::kLBRACE: | 962 case Token::kLBRACE: |
| 940 case Token::kLPAREN: | 963 case Token::kLPAREN: |
| 941 case Token::kLBRACK: | 964 case Token::kLBRACK: |
| 942 token_stack.Add(token); | 965 token_stack.Add(token); |
| 943 break; | 966 break; |
| 944 case Token::kRBRACE: | 967 case Token::kRBRACE: |
| 945 is_match = token_stack.Last() == Token::kLBRACE; | 968 is_match = token_stack.Last() == Token::kLBRACE; |
| 946 token_stack.RemoveLast(); | 969 token_stack.RemoveLast(); |
| 947 break; | 970 break; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1028 } | 1051 } |
| 1029 } | 1052 } |
| 1030 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 1053 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
| 1031 ConsumeToken(); | 1054 ConsumeToken(); |
| 1032 ExpectToken(Token::kPERIOD); | 1055 ExpectToken(Token::kPERIOD); |
| 1033 this_seen = true; | 1056 this_seen = true; |
| 1034 parameter.is_field_initializer = true; | 1057 parameter.is_field_initializer = true; |
| 1035 } | 1058 } |
| 1036 | 1059 |
| 1037 // At this point, we must see an identifier for the parameter name. | 1060 // At this point, we must see an identifier for the parameter name. |
| 1038 parameter.name_pos = token_index_; | 1061 parameter.name_pos = TokenIndex(); |
| 1039 parameter.name = ExpectIdentifier("parameter name expected"); | 1062 parameter.name = ExpectIdentifier("parameter name expected"); |
| 1040 if (parameter.is_field_initializer) { | 1063 if (parameter.is_field_initializer) { |
| 1041 params->has_field_initializer = true; | 1064 params->has_field_initializer = true; |
| 1042 } | 1065 } |
| 1043 | 1066 |
| 1044 // Check for duplicate formal parameters. | 1067 // Check for duplicate formal parameters. |
| 1045 const intptr_t num_existing_parameters = | 1068 const intptr_t num_existing_parameters = |
| 1046 params->num_fixed_parameters + params->num_optional_parameters; | 1069 params->num_fixed_parameters + params->num_optional_parameters; |
| 1047 for (intptr_t i = 0; i < num_existing_parameters; i++) { | 1070 for (intptr_t i = 0; i < num_existing_parameters; i++) { |
| 1048 ParamDesc& existing_parameter = (*params->parameters)[i]; | 1071 ParamDesc& existing_parameter = (*params->parameters)[i]; |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1282 args_array->AddElement(function_args.NodeAt(i)); | 1305 args_array->AddElement(function_args.NodeAt(i)); |
| 1283 } | 1306 } |
| 1284 arguments->Add(args_array); | 1307 arguments->Add(args_array); |
| 1285 return arguments; | 1308 return arguments; |
| 1286 } | 1309 } |
| 1287 | 1310 |
| 1288 | 1311 |
| 1289 AstNode* Parser::ParseSuperCall(const String& function_name) { | 1312 AstNode* Parser::ParseSuperCall(const String& function_name) { |
| 1290 TRACE_PARSER("ParseSuperCall"); | 1313 TRACE_PARSER("ParseSuperCall"); |
| 1291 ASSERT(CurrentToken() == Token::kLPAREN); | 1314 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1292 const intptr_t supercall_pos = token_index_; | 1315 const intptr_t supercall_pos = TokenIndex(); |
| 1293 | 1316 |
| 1294 bool is_no_such_method = false; | 1317 bool is_no_such_method = false; |
| 1295 const Function& super_function = Function::ZoneHandle( | 1318 const Function& super_function = Function::ZoneHandle( |
| 1296 GetSuperFunction(supercall_pos, function_name, &is_no_such_method)); | 1319 GetSuperFunction(supercall_pos, function_name, &is_no_such_method)); |
| 1297 | 1320 |
| 1298 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1321 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1299 // 'this' parameter is the first argument to super call. | 1322 // 'this' parameter is the first argument to super call. |
| 1300 AstNode* receiver = LoadReceiver(supercall_pos); | 1323 AstNode* receiver = LoadReceiver(supercall_pos); |
| 1301 arguments->Add(receiver); | 1324 arguments->Add(receiver); |
| 1302 ParseActualParameters(arguments, kAllowConst); | 1325 ParseActualParameters(arguments, kAllowConst); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1315 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { | 1338 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { |
| 1316 return true; | 1339 return true; |
| 1317 } | 1340 } |
| 1318 return false; | 1341 return false; |
| 1319 } | 1342 } |
| 1320 | 1343 |
| 1321 | 1344 |
| 1322 AstNode* Parser::ParseSuperOperator() { | 1345 AstNode* Parser::ParseSuperOperator() { |
| 1323 TRACE_PARSER("ParseSuperOperator"); | 1346 TRACE_PARSER("ParseSuperOperator"); |
| 1324 AstNode* super_op = NULL; | 1347 AstNode* super_op = NULL; |
| 1325 const intptr_t operator_pos = token_index_; | 1348 const intptr_t operator_pos = TokenIndex(); |
| 1326 | 1349 |
| 1327 if (CurrentToken() == Token::kLBRACK) { | 1350 if (CurrentToken() == Token::kLBRACK) { |
| 1328 ConsumeToken(); | 1351 ConsumeToken(); |
| 1329 AstNode* index_expr = ParseExpr(kAllowConst); | 1352 AstNode* index_expr = ParseExpr(kAllowConst); |
| 1330 ExpectToken(Token::kRBRACK); | 1353 ExpectToken(Token::kRBRACK); |
| 1331 | 1354 |
| 1332 if (Token::IsAssignmentOperator(CurrentToken()) && | 1355 if (Token::IsAssignmentOperator(CurrentToken()) && |
| 1333 (CurrentToken() != Token::kASSIGN)) { | 1356 (CurrentToken() != Token::kASSIGN)) { |
| 1334 // Compound assignment. Ensure side effects in index expression | 1357 // Compound assignment. Ensure side effects in index expression |
| 1335 // only execute once. If the index is not a local variable or an | 1358 // only execute once. If the index is not a local variable or an |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1440 CaptureReceiver(); | 1463 CaptureReceiver(); |
| 1441 } | 1464 } |
| 1442 } | 1465 } |
| 1443 } | 1466 } |
| 1444 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 1467 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 1445 } | 1468 } |
| 1446 | 1469 |
| 1447 | 1470 |
| 1448 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { | 1471 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { |
| 1449 TRACE_PARSER("ParseSuperFieldAccess"); | 1472 TRACE_PARSER("ParseSuperFieldAccess"); |
| 1450 const intptr_t field_pos = token_index_; | 1473 const intptr_t field_pos = TokenIndex(); |
| 1451 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1474 const Class& super_class = Class::Handle(current_class().SuperClass()); |
| 1452 if (super_class.IsNull()) { | 1475 if (super_class.IsNull()) { |
| 1453 ErrorMsg("class '%s' does not have a superclass", | 1476 ErrorMsg("class '%s' does not have a superclass", |
| 1454 String::Handle(current_class().Name()).ToCString()); | 1477 String::Handle(current_class().Name()).ToCString()); |
| 1455 } | 1478 } |
| 1456 AstNode* implicit_argument = LoadReceiver(field_pos); | 1479 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 1457 | 1480 |
| 1458 const String& getter_name = | 1481 const String& getter_name = |
| 1459 String::ZoneHandle(Field::GetterName(field_name)); | 1482 String::ZoneHandle(Field::GetterName(field_name)); |
| 1460 const Function& super_getter = Function::ZoneHandle( | 1483 const Function& super_getter = Function::ZoneHandle( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 setter_arguments->Add(implicit_argument); | 1526 setter_arguments->Add(implicit_argument); |
| 1504 setter_arguments->Add(value); | 1527 setter_arguments->Add(value); |
| 1505 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); | 1528 super_field = new StaticCallNode(field_pos, super_setter, setter_arguments); |
| 1506 } | 1529 } |
| 1507 return super_field; | 1530 return super_field; |
| 1508 } | 1531 } |
| 1509 | 1532 |
| 1510 | 1533 |
| 1511 void Parser::GenerateSuperConstructorCall(const Class& cls, | 1534 void Parser::GenerateSuperConstructorCall(const Class& cls, |
| 1512 LocalVariable* receiver) { | 1535 LocalVariable* receiver) { |
| 1513 const intptr_t supercall_pos = token_index_; | 1536 const intptr_t supercall_pos = TokenIndex(); |
| 1514 const Class& super_class = Class::Handle(cls.SuperClass()); | 1537 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1515 // Omit the implicit super() if there is no super class (i.e. | 1538 // Omit the implicit super() if there is no super class (i.e. |
| 1516 // we're not compiling class Object), or if the super class is an | 1539 // we're not compiling class Object), or if the super class is an |
| 1517 // artificially generated "wrapper class" that has no constructor. | 1540 // artificially generated "wrapper class" that has no constructor. |
| 1518 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { | 1541 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { |
| 1519 return; | 1542 return; |
| 1520 } | 1543 } |
| 1521 String& ctor_name = String::Handle(super_class.Name()); | 1544 String& ctor_name = String::Handle(super_class.Name()); |
| 1522 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1545 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1523 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1546 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1542 CheckFunctionIsCallable(supercall_pos, super_ctor); | 1565 CheckFunctionIsCallable(supercall_pos, super_ctor); |
| 1543 current_block_->statements->Add( | 1566 current_block_->statements->Add( |
| 1544 new StaticCallNode(supercall_pos, super_ctor, arguments)); | 1567 new StaticCallNode(supercall_pos, super_ctor, arguments)); |
| 1545 } | 1568 } |
| 1546 | 1569 |
| 1547 | 1570 |
| 1548 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 1571 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 1549 LocalVariable* receiver) { | 1572 LocalVariable* receiver) { |
| 1550 TRACE_PARSER("ParseSuperInitializer"); | 1573 TRACE_PARSER("ParseSuperInitializer"); |
| 1551 ASSERT(CurrentToken() == Token::kSUPER); | 1574 ASSERT(CurrentToken() == Token::kSUPER); |
| 1552 const intptr_t supercall_pos = token_index_; | 1575 const intptr_t supercall_pos = TokenIndex(); |
| 1553 ConsumeToken(); | 1576 ConsumeToken(); |
| 1554 const Class& super_class = Class::Handle(cls.SuperClass()); | 1577 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1555 ASSERT(!super_class.IsNull()); | 1578 ASSERT(!super_class.IsNull()); |
| 1556 String& ctor_name = String::Handle(super_class.Name()); | 1579 String& ctor_name = String::Handle(super_class.Name()); |
| 1557 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1580 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1558 if (CurrentToken() == Token::kPERIOD) { | 1581 if (CurrentToken() == Token::kPERIOD) { |
| 1559 ConsumeToken(); | 1582 ConsumeToken(); |
| 1560 ctor_suffix = String::Concat( | 1583 ctor_suffix = String::Concat( |
| 1561 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1584 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1562 } | 1585 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1592 "super class constructor '%s' not found", | 1615 "super class constructor '%s' not found", |
| 1593 ctor_name.ToCString()); | 1616 ctor_name.ToCString()); |
| 1594 } | 1617 } |
| 1595 CheckFunctionIsCallable(supercall_pos, super_ctor); | 1618 CheckFunctionIsCallable(supercall_pos, super_ctor); |
| 1596 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 1619 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 1597 } | 1620 } |
| 1598 | 1621 |
| 1599 | 1622 |
| 1600 AstNode* Parser::ParseInitializer(const Class& cls, LocalVariable* receiver) { | 1623 AstNode* Parser::ParseInitializer(const Class& cls, LocalVariable* receiver) { |
| 1601 TRACE_PARSER("ParseInitializer"); | 1624 TRACE_PARSER("ParseInitializer"); |
| 1602 const intptr_t field_pos = token_index_; | 1625 const intptr_t field_pos = TokenIndex(); |
| 1603 if (CurrentToken() == Token::kTHIS) { | 1626 if (CurrentToken() == Token::kTHIS) { |
| 1604 ConsumeToken(); | 1627 ConsumeToken(); |
| 1605 ExpectToken(Token::kPERIOD); | 1628 ExpectToken(Token::kPERIOD); |
| 1606 } | 1629 } |
| 1607 const String& field_name = *ExpectIdentifier("field name expected"); | 1630 const String& field_name = *ExpectIdentifier("field name expected"); |
| 1608 ExpectToken(Token::kASSIGN); | 1631 ExpectToken(Token::kASSIGN); |
| 1609 | 1632 |
| 1610 const bool saved_mode = SetAllowFunctionLiterals(false); | 1633 const bool saved_mode = SetAllowFunctionLiterals(false); |
| 1611 // "this" must not be accessible in initializer expressions. | 1634 // "this" must not be accessible in initializer expressions. |
| 1612 receiver->set_invisible(true); | 1635 receiver->set_invisible(true); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1656 Field* inst_field; | 1679 Field* inst_field; |
| 1657 AstNode* expr; | 1680 AstNode* expr; |
| 1658 }; | 1681 }; |
| 1659 | 1682 |
| 1660 | 1683 |
| 1661 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1684 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 1662 GrowableArray<FieldInitExpression>* initializers) { | 1685 GrowableArray<FieldInitExpression>* initializers) { |
| 1663 TRACE_PARSER("ParseInitializedInstanceFields"); | 1686 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 1664 const Array& fields = Array::Handle(cls.fields()); | 1687 const Array& fields = Array::Handle(cls.fields()); |
| 1665 Field& f = Field::Handle(); | 1688 Field& f = Field::Handle(); |
| 1666 const intptr_t saved_pos = token_index_; | 1689 const intptr_t saved_pos = TokenIndex(); |
| 1667 for (int i = 0; i < fields.Length(); i++) { | 1690 for (int i = 0; i < fields.Length(); i++) { |
| 1668 f ^= fields.At(i); | 1691 f ^= fields.At(i); |
| 1669 if (!f.is_static() && f.has_initializer()) { | 1692 if (!f.is_static() && f.has_initializer()) { |
| 1670 Field& field = Field::ZoneHandle(); | 1693 Field& field = Field::ZoneHandle(); |
| 1671 field ^= fields.At(i); | 1694 field ^= fields.At(i); |
| 1672 intptr_t field_pos = field.token_index(); | 1695 intptr_t field_pos = field.token_index(); |
| 1673 SetPosition(field_pos); | 1696 SetPosition(field_pos); |
| 1674 ASSERT(IsIdentifier()); | 1697 ASSERT(IsIdentifier()); |
| 1675 ConsumeToken(); | 1698 ConsumeToken(); |
| 1676 ExpectToken(Token::kASSIGN); | 1699 ExpectToken(Token::kASSIGN); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1723 GenerateSuperConstructorCall(cls, receiver); | 1746 GenerateSuperConstructorCall(cls, receiver); |
| 1724 } | 1747 } |
| 1725 CheckConstFieldsInitialized(cls); | 1748 CheckConstFieldsInitialized(cls); |
| 1726 } | 1749 } |
| 1727 | 1750 |
| 1728 | 1751 |
| 1729 void Parser::ParseConstructorRedirection(const Class& cls, | 1752 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1730 LocalVariable* receiver) { | 1753 LocalVariable* receiver) { |
| 1731 TRACE_PARSER("ParseConstructorRedirection"); | 1754 TRACE_PARSER("ParseConstructorRedirection"); |
| 1732 ASSERT(CurrentToken() == Token::kTHIS); | 1755 ASSERT(CurrentToken() == Token::kTHIS); |
| 1733 const intptr_t call_pos = token_index_; | 1756 const intptr_t call_pos = TokenIndex(); |
| 1734 ConsumeToken(); | 1757 ConsumeToken(); |
| 1735 String& ctor_name = String::Handle(cls.Name()); | 1758 String& ctor_name = String::Handle(cls.Name()); |
| 1736 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1759 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1737 | 1760 |
| 1738 if (CurrentToken() == Token::kPERIOD) { | 1761 if (CurrentToken() == Token::kPERIOD) { |
| 1739 ConsumeToken(); | 1762 ConsumeToken(); |
| 1740 ctor_suffix = String::Concat( | 1763 ctor_suffix = String::Concat( |
| 1741 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1764 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1742 } | 1765 } |
| 1743 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1766 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1766 ctor_name.ToCString()); | 1789 ctor_name.ToCString()); |
| 1767 } | 1790 } |
| 1768 CheckFunctionIsCallable(call_pos, redirect_ctor); | 1791 CheckFunctionIsCallable(call_pos, redirect_ctor); |
| 1769 current_block_->statements->Add( | 1792 current_block_->statements->Add( |
| 1770 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 1793 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 1771 } | 1794 } |
| 1772 | 1795 |
| 1773 | 1796 |
| 1774 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 1797 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 1775 ASSERT(func.IsConstructor()); | 1798 ASSERT(func.IsConstructor()); |
| 1776 const intptr_t ctor_pos = token_index_; | 1799 const intptr_t ctor_pos = TokenIndex(); |
| 1777 | 1800 |
| 1778 // Implicit 'this' is the only parameter/local variable. | 1801 // Implicit 'this' is the only parameter/local variable. |
| 1779 OpenFunctionBlock(func); | 1802 OpenFunctionBlock(func); |
| 1780 | 1803 |
| 1781 // Parse expressions of instance fields that have an explicit | 1804 // Parse expressions of instance fields that have an explicit |
| 1782 // initializers. | 1805 // initializers. |
| 1783 GrowableArray<FieldInitExpression> initializers; | 1806 GrowableArray<FieldInitExpression> initializers; |
| 1784 Class& cls = Class::Handle(func.owner()); | 1807 Class& cls = Class::Handle(func.owner()); |
| 1785 ParseInitializedInstanceFields(cls, &initializers); | 1808 ParseInitializedInstanceFields(cls, &initializers); |
| 1786 | 1809 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1842 return MakeImplicitConstructor(func); | 1865 return MakeImplicitConstructor(func); |
| 1843 } | 1866 } |
| 1844 | 1867 |
| 1845 OpenFunctionBlock(func); | 1868 OpenFunctionBlock(func); |
| 1846 ParamList params; | 1869 ParamList params; |
| 1847 const bool allow_explicit_default_values = true; | 1870 const bool allow_explicit_default_values = true; |
| 1848 ASSERT(CurrentToken() == Token::kLPAREN); | 1871 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1849 | 1872 |
| 1850 // Add implicit receiver parameter which is passed the allocated | 1873 // Add implicit receiver parameter which is passed the allocated |
| 1851 // but uninitialized instance to construct. | 1874 // but uninitialized instance to construct. |
| 1852 params.AddReceiver(token_index_); | 1875 params.AddReceiver(TokenIndex()); |
| 1853 | 1876 |
| 1854 // Add implicit parameter for construction phase. | 1877 // Add implicit parameter for construction phase. |
| 1855 params.AddFinalParameter( | 1878 params.AddFinalParameter( |
| 1856 token_index_, | 1879 TokenIndex(), |
| 1857 kPhaseParameterName, | 1880 kPhaseParameterName, |
| 1858 &Type::ZoneHandle(Type::DynamicType())); | 1881 &Type::ZoneHandle(Type::DynamicType())); |
| 1859 | 1882 |
| 1860 if (func.is_const()) { | 1883 if (func.is_const()) { |
| 1861 params.SetImplicitlyFinal(); | 1884 params.SetImplicitlyFinal(); |
| 1862 } | 1885 } |
| 1863 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 1886 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 1864 | 1887 |
| 1865 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 1888 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 1866 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1889 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1924 } | 1947 } |
| 1925 } | 1948 } |
| 1926 | 1949 |
| 1927 // Now parse the explicit initializer list or constructor redirection. | 1950 // Now parse the explicit initializer list or constructor redirection. |
| 1928 ParseInitializers(cls, receiver); | 1951 ParseInitializers(cls, receiver); |
| 1929 | 1952 |
| 1930 SequenceNode* init_statements = CloseBlock(); | 1953 SequenceNode* init_statements = CloseBlock(); |
| 1931 if (init_statements->length() > 0) { | 1954 if (init_statements->length() > 0) { |
| 1932 // Generate guard around the initializer code. | 1955 // Generate guard around the initializer code. |
| 1933 LocalVariable* phase_param = LookupPhaseParameter(); | 1956 LocalVariable* phase_param = LookupPhaseParameter(); |
| 1934 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param); | 1957 AstNode* phase_value = new LoadLocalNode(TokenIndex(), *phase_param); |
| 1935 AstNode* phase_check = new BinaryOpNode( | 1958 AstNode* phase_check = new BinaryOpNode( |
| 1936 token_index_, Token::kBIT_AND, phase_value, | 1959 TokenIndex(), Token::kBIT_AND, phase_value, |
| 1937 new LiteralNode(token_index_, | 1960 new LiteralNode(TokenIndex(), |
| 1938 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 1961 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 1939 AstNode* comparison = | 1962 AstNode* comparison = |
| 1940 new ComparisonNode(token_index_, Token::kNE_STRICT, | 1963 new ComparisonNode(TokenIndex(), Token::kNE_STRICT, |
| 1941 phase_check, | 1964 phase_check, |
| 1942 new LiteralNode(token_index_, | 1965 new LiteralNode(TokenIndex(), |
| 1943 Smi::ZoneHandle(Smi::New(0)))); | 1966 Smi::ZoneHandle(Smi::New(0)))); |
| 1944 AstNode* guarded_init_statements = | 1967 AstNode* guarded_init_statements = |
| 1945 new IfNode(token_index_, comparison, init_statements, NULL); | 1968 new IfNode(TokenIndex(), comparison, init_statements, NULL); |
| 1946 current_block_->statements->Add(guarded_init_statements); | 1969 current_block_->statements->Add(guarded_init_statements); |
| 1947 } | 1970 } |
| 1948 | 1971 |
| 1949 // Parsing of initializers done. Now we parse the constructor body | 1972 // Parsing of initializers done. Now we parse the constructor body |
| 1950 // and add the implicit super call to the super constructor's body | 1973 // and add the implicit super call to the super constructor's body |
| 1951 // if necessary. | 1974 // if necessary. |
| 1952 StaticCallNode* super_call = NULL; | 1975 StaticCallNode* super_call = NULL; |
| 1953 // Look for the super initializer call in the sequence of initializer | 1976 // Look for the super initializer call in the sequence of initializer |
| 1954 // statements. If it exists and is not the last initializer statement, | 1977 // statements. If it exists and is not the last initializer statement, |
| 1955 // we need to create an implicit super call to the super constructor's | 1978 // we need to create an implicit super call to the super constructor's |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1988 } | 2011 } |
| 1989 } | 2012 } |
| 1990 OpenBlock(); // Block to collect constructor body nodes. | 2013 OpenBlock(); // Block to collect constructor body nodes. |
| 1991 | 2014 |
| 1992 // Insert the implicit super call to the super constructor body. | 2015 // Insert the implicit super call to the super constructor body. |
| 1993 if (super_call != NULL) { | 2016 if (super_call != NULL) { |
| 1994 ArgumentListNode* initializer_args = super_call->arguments(); | 2017 ArgumentListNode* initializer_args = super_call->arguments(); |
| 1995 const Function& super_ctor = super_call->function(); | 2018 const Function& super_ctor = super_call->function(); |
| 1996 // Patch the initializer call so it only executes the super initializer. | 2019 // Patch the initializer call so it only executes the super initializer. |
| 1997 initializer_args->SetNodeAt(1, | 2020 initializer_args->SetNodeAt(1, |
| 1998 new LiteralNode(token_index_, | 2021 new LiteralNode(TokenIndex(), |
| 1999 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 2022 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 2000 | 2023 |
| 2001 ArgumentListNode* super_call_args = new ArgumentListNode(token_index_); | 2024 ArgumentListNode* super_call_args = new ArgumentListNode(TokenIndex()); |
| 2002 // First argument is the receiver. | 2025 // First argument is the receiver. |
| 2003 super_call_args->Add(new LoadLocalNode(token_index_, *receiver)); | 2026 super_call_args->Add(new LoadLocalNode(TokenIndex(), *receiver)); |
| 2004 // Second argument is the construction phase argument. | 2027 // Second argument is the construction phase argument. |
| 2005 AstNode* phase_parameter = | 2028 AstNode* phase_parameter = |
| 2006 new LiteralNode(token_index_, | 2029 new LiteralNode(TokenIndex(), |
| 2007 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); | 2030 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); |
| 2008 super_call_args->Add(phase_parameter); | 2031 super_call_args->Add(phase_parameter); |
| 2009 super_call_args->set_names(initializer_args->names()); | 2032 super_call_args->set_names(initializer_args->names()); |
| 2010 for (int i = 2; i < initializer_args->length(); i++) { | 2033 for (int i = 2; i < initializer_args->length(); i++) { |
| 2011 AstNode* arg = initializer_args->NodeAt(i); | 2034 AstNode* arg = initializer_args->NodeAt(i); |
| 2012 if (arg->IsLiteralNode()) { | 2035 if (arg->IsLiteralNode()) { |
| 2013 LiteralNode* lit = arg->AsLiteralNode(); | 2036 LiteralNode* lit = arg->AsLiteralNode(); |
| 2014 super_call_args->Add(new LiteralNode(token_index_, lit->literal())); | 2037 super_call_args->Add(new LiteralNode(TokenIndex(), lit->literal())); |
| 2015 } else { | 2038 } else { |
| 2016 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); | 2039 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); |
| 2017 if (arg->IsLoadLocalNode()) { | 2040 if (arg->IsLoadLocalNode()) { |
| 2018 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); | 2041 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); |
| 2019 super_call_args->Add(new LoadLocalNode(token_index_, temp)); | 2042 super_call_args->Add(new LoadLocalNode(TokenIndex(), temp)); |
| 2020 } else if (arg->IsStoreLocalNode()) { | 2043 } else if (arg->IsStoreLocalNode()) { |
| 2021 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); | 2044 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); |
| 2022 super_call_args->Add(new LoadLocalNode(token_index_, temp)); | 2045 super_call_args->Add(new LoadLocalNode(TokenIndex(), temp)); |
| 2023 } | 2046 } |
| 2024 } | 2047 } |
| 2025 } | 2048 } |
| 2026 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), | 2049 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), |
| 2027 super_call_args->names())); | 2050 super_call_args->names())); |
| 2028 current_block_->statements->Add( | 2051 current_block_->statements->Add( |
| 2029 new StaticCallNode(token_index_, super_ctor, super_call_args)); | 2052 new StaticCallNode(TokenIndex(), super_ctor, super_call_args)); |
| 2030 } | 2053 } |
| 2031 | 2054 |
| 2032 if (CurrentToken() == Token::kLBRACE) { | 2055 if (CurrentToken() == Token::kLBRACE) { |
| 2033 ConsumeToken(); | 2056 ConsumeToken(); |
| 2034 ParseStatementSequence(); | 2057 ParseStatementSequence(); |
| 2035 ExpectToken(Token::kRBRACE); | 2058 ExpectToken(Token::kRBRACE); |
| 2036 } else if (CurrentToken() == Token::kARROW) { | 2059 } else if (CurrentToken() == Token::kARROW) { |
| 2037 ErrorMsg("constructors may not return a value"); | 2060 ErrorMsg("constructors may not return a value"); |
| 2038 } else if (IsLiteral("native")) { | 2061 } else if (IsLiteral("native")) { |
| 2039 ErrorMsg("native constructors not supported"); | 2062 ErrorMsg("native constructors not supported"); |
| 2040 } else if (CurrentToken() == Token::kSEMICOLON) { | 2063 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 2041 // Some constructors have no function body. | 2064 // Some constructors have no function body. |
| 2042 ConsumeToken(); | 2065 ConsumeToken(); |
| 2043 } else { | 2066 } else { |
| 2044 UnexpectedToken(); | 2067 UnexpectedToken(); |
| 2045 } | 2068 } |
| 2046 | 2069 |
| 2047 SequenceNode* ctor_block = CloseBlock(); | 2070 SequenceNode* ctor_block = CloseBlock(); |
| 2048 if (ctor_block->length() > 0) { | 2071 if (ctor_block->length() > 0) { |
| 2049 // Generate guard around the constructor body code. | 2072 // Generate guard around the constructor body code. |
| 2050 LocalVariable* phase_param = LookupPhaseParameter(); | 2073 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2051 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param); | 2074 AstNode* phase_value = new LoadLocalNode(TokenIndex(), *phase_param); |
| 2052 AstNode* phase_check = | 2075 AstNode* phase_check = |
| 2053 new BinaryOpNode(token_index_, Token::kBIT_AND, | 2076 new BinaryOpNode(TokenIndex(), Token::kBIT_AND, |
| 2054 phase_value, | 2077 phase_value, |
| 2055 new LiteralNode(token_index_, | 2078 new LiteralNode(TokenIndex(), |
| 2056 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); | 2079 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); |
| 2057 AstNode* comparison = | 2080 AstNode* comparison = |
| 2058 new ComparisonNode(token_index_, Token::kNE_STRICT, | 2081 new ComparisonNode(TokenIndex(), Token::kNE_STRICT, |
| 2059 phase_check, | 2082 phase_check, |
| 2060 new LiteralNode(token_index_, | 2083 new LiteralNode(TokenIndex(), |
| 2061 Smi::ZoneHandle(Smi::New(0)))); | 2084 Smi::ZoneHandle(Smi::New(0)))); |
| 2062 AstNode* guarded_block_statements = | 2085 AstNode* guarded_block_statements = |
| 2063 new IfNode(token_index_, comparison, ctor_block, NULL); | 2086 new IfNode(TokenIndex(), comparison, ctor_block, NULL); |
| 2064 current_block_->statements->Add(guarded_block_statements); | 2087 current_block_->statements->Add(guarded_block_statements); |
| 2065 } | 2088 } |
| 2066 | 2089 |
| 2067 SequenceNode* statements = CloseBlock(); | 2090 SequenceNode* statements = CloseBlock(); |
| 2068 return statements; | 2091 return statements; |
| 2069 } | 2092 } |
| 2070 | 2093 |
| 2071 | 2094 |
| 2072 // Parser is at the opening parenthesis of the formal parameter | 2095 // Parser is at the opening parenthesis of the formal parameter |
| 2073 // declaration of the function or constructor. | 2096 // declaration of the function or constructor. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2085 ParamList params; | 2108 ParamList params; |
| 2086 // Static functions do not have a receiver. | 2109 // Static functions do not have a receiver. |
| 2087 // An instance closure may capture and access the receiver, but via the | 2110 // An instance closure may capture and access the receiver, but via the |
| 2088 // context and not via the first formal parameter. | 2111 // context and not via the first formal parameter. |
| 2089 // The first parameter of a factory is the AbstractTypeArguments vector of the | 2112 // The first parameter of a factory is the AbstractTypeArguments vector of the |
| 2090 // type of the instance to be allocated. We name this hidden parameter 'this'. | 2113 // type of the instance to be allocated. We name this hidden parameter 'this'. |
| 2091 const bool has_receiver = !func.IsClosureFunction() && | 2114 const bool has_receiver = !func.IsClosureFunction() && |
| 2092 (!func.is_static() || func.IsFactory()); | 2115 (!func.is_static() || func.IsFactory()); |
| 2093 const bool allow_explicit_default_values = true; | 2116 const bool allow_explicit_default_values = true; |
| 2094 if (has_receiver) { | 2117 if (has_receiver) { |
| 2095 params.AddReceiver(token_index_); | 2118 params.AddReceiver(TokenIndex()); |
| 2096 } | 2119 } |
| 2097 ASSERT(CurrentToken() == Token::kLPAREN); | 2120 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2098 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 2121 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 2099 | 2122 |
| 2100 // The number of parameters and their type are not yet set in local functions, | 2123 // The number of parameters and their type are not yet set in local functions, |
| 2101 // since they are not 'top-level' parsed. | 2124 // since they are not 'top-level' parsed. |
| 2102 if (func.IsLocalFunction()) { | 2125 if (func.IsLocalFunction()) { |
| 2103 AddFormalParamsToFunction(¶ms, func); | 2126 AddFormalParamsToFunction(¶ms, func); |
| 2104 } | 2127 } |
| 2105 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2128 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2133 } | 2156 } |
| 2134 } | 2157 } |
| 2135 | 2158 |
| 2136 OpenBlock(); // Open a nested scope for the outermost function block. | 2159 OpenBlock(); // Open a nested scope for the outermost function block. |
| 2137 if (CurrentToken() == Token::kLBRACE) { | 2160 if (CurrentToken() == Token::kLBRACE) { |
| 2138 ConsumeToken(); | 2161 ConsumeToken(); |
| 2139 ParseStatementSequence(); | 2162 ParseStatementSequence(); |
| 2140 ExpectToken(Token::kRBRACE); | 2163 ExpectToken(Token::kRBRACE); |
| 2141 } else if (CurrentToken() == Token::kARROW) { | 2164 } else if (CurrentToken() == Token::kARROW) { |
| 2142 ConsumeToken(); | 2165 ConsumeToken(); |
| 2143 const intptr_t expr_pos = token_index_; | 2166 const intptr_t expr_pos = TokenIndex(); |
| 2144 AstNode* expr = ParseExpr(kAllowConst); | 2167 AstNode* expr = ParseExpr(kAllowConst); |
| 2145 ASSERT(expr != NULL); | 2168 ASSERT(expr != NULL); |
| 2146 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 2169 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 2147 } else if (IsLiteral("native")) { | 2170 } else if (IsLiteral("native")) { |
| 2148 ParseNativeFunctionBlock(¶ms, func); | 2171 ParseNativeFunctionBlock(¶ms, func); |
| 2149 } else { | 2172 } else { |
| 2150 UnexpectedToken(); | 2173 UnexpectedToken(); |
| 2151 } | 2174 } |
| 2152 SequenceNode* body = CloseBlock(); | 2175 SequenceNode* body = CloseBlock(); |
| 2153 current_block_->statements->Add(body); | 2176 current_block_->statements->Add(body); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2201 SetAllowFunctionLiterals(true); | 2224 SetAllowFunctionLiterals(true); |
| 2202 } | 2225 } |
| 2203 } while (CurrentToken() == Token::kCOMMA); | 2226 } while (CurrentToken() == Token::kCOMMA); |
| 2204 } | 2227 } |
| 2205 | 2228 |
| 2206 | 2229 |
| 2207 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 2230 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
| 2208 TRACE_PARSER("ParseQualIdent"); | 2231 TRACE_PARSER("ParseQualIdent"); |
| 2209 ASSERT(IsIdentifier()); | 2232 ASSERT(IsIdentifier()); |
| 2210 ASSERT(!current_class().IsNull()); | 2233 ASSERT(!current_class().IsNull()); |
| 2211 qual_ident->ident_pos = token_index_; | 2234 qual_ident->ident_pos = TokenIndex(); |
| 2212 qual_ident->ident = CurrentLiteral(); | 2235 qual_ident->ident = CurrentLiteral(); |
| 2213 qual_ident->lib_prefix = NULL; | 2236 qual_ident->lib_prefix = NULL; |
| 2214 ConsumeToken(); | 2237 ConsumeToken(); |
| 2215 if (CurrentToken() == Token::kPERIOD) { | 2238 if (CurrentToken() == Token::kPERIOD) { |
| 2216 // An identifier cannot be resolved in a local scope when top level parsing. | 2239 // An identifier cannot be resolved in a local scope when top level parsing. |
| 2217 if (is_top_level_ || | 2240 if (is_top_level_ || |
| 2218 !ResolveIdentInLocalScope(qual_ident->ident_pos, | 2241 !ResolveIdentInLocalScope(qual_ident->ident_pos, |
| 2219 *(qual_ident->ident), | 2242 *(qual_ident->ident), |
| 2220 NULL)) { | 2243 NULL)) { |
| 2221 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 2244 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 2222 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 2245 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 2223 if (!lib_prefix.IsNull()) { | 2246 if (!lib_prefix.IsNull()) { |
| 2224 // We have a library prefix qualified identifier, unless the prefix is | 2247 // We have a library prefix qualified identifier, unless the prefix is |
| 2225 // shadowed by a type parameter in scope. | 2248 // shadowed by a type parameter in scope. |
| 2226 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 2249 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 2227 if (scope_class.IsNull() || | 2250 if (scope_class.IsNull() || |
| 2228 (scope_class.LookupTypeParameter(*(qual_ident->ident), | 2251 (scope_class.LookupTypeParameter(*(qual_ident->ident), |
| 2229 token_index_) == | 2252 TokenIndex()) == |
| 2230 TypeParameter::null())) { | 2253 TypeParameter::null())) { |
| 2231 ConsumeToken(); // Consume the kPERIOD token. | 2254 ConsumeToken(); // Consume the kPERIOD token. |
| 2232 qual_ident->lib_prefix = &lib_prefix; | 2255 qual_ident->lib_prefix = &lib_prefix; |
| 2233 qual_ident->ident_pos = token_index_; | 2256 qual_ident->ident_pos = TokenIndex(); |
| 2234 qual_ident->ident = | 2257 qual_ident->ident = |
| 2235 ExpectIdentifier("identifier expected after '.'"); | 2258 ExpectIdentifier("identifier expected after '.'"); |
| 2236 } | 2259 } |
| 2237 } | 2260 } |
| 2238 } | 2261 } |
| 2239 } | 2262 } |
| 2240 } | 2263 } |
| 2241 | 2264 |
| 2242 | 2265 |
| 2243 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 2266 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 2244 TRACE_PARSER("ParseMethodOrConstructor"); | 2267 TRACE_PARSER("ParseMethodOrConstructor"); |
| 2245 ASSERT(CurrentToken() == Token::kLPAREN); | 2268 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2246 intptr_t method_pos = this->token_index_; | 2269 intptr_t method_pos = this->TokenIndex(); |
| 2247 ASSERT(method->type != NULL); | 2270 ASSERT(method->type != NULL); |
| 2248 ASSERT(method->name_pos > 0); | 2271 ASSERT(method->name_pos > 0); |
| 2249 ASSERT(current_member_ == method); | 2272 ASSERT(current_member_ == method); |
| 2250 | 2273 |
| 2251 if (method->has_var) { | 2274 if (method->has_var) { |
| 2252 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 2275 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); |
| 2253 } | 2276 } |
| 2254 if (method->has_final) { | 2277 if (method->has_final) { |
| 2255 ErrorMsg(method->name_pos, "'final' not allowed for methods"); | 2278 ErrorMsg(method->name_pos, "'final' not allowed for methods"); |
| 2256 } | 2279 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2279 "field or method '%s' already defined", method->name->ToCString()); | 2302 "field or method '%s' already defined", method->name->ToCString()); |
| 2280 } | 2303 } |
| 2281 | 2304 |
| 2282 // Parse the formal parameters. | 2305 // Parse the formal parameters. |
| 2283 // The first parameter of factory methods is an implicit parameter called | 2306 // The first parameter of factory methods is an implicit parameter called |
| 2284 // 'this' of type AbstractTypeArguments. | 2307 // 'this' of type AbstractTypeArguments. |
| 2285 const bool has_this_param = | 2308 const bool has_this_param = |
| 2286 !method->has_static || method->IsConstructor() || method->has_factory; | 2309 !method->has_static || method->IsConstructor() || method->has_factory; |
| 2287 const bool are_implicitly_final = method->has_const; | 2310 const bool are_implicitly_final = method->has_const; |
| 2288 const bool allow_explicit_default_values = true; | 2311 const bool allow_explicit_default_values = true; |
| 2289 const intptr_t formal_param_pos = token_index_; | 2312 const intptr_t formal_param_pos = TokenIndex(); |
| 2290 method->params.Clear(); | 2313 method->params.Clear(); |
| 2291 if (has_this_param) { | 2314 if (has_this_param) { |
| 2292 method->params.AddReceiver(formal_param_pos); | 2315 method->params.AddReceiver(formal_param_pos); |
| 2293 } | 2316 } |
| 2294 // Constructors have an implicit parameter for the construction phase. | 2317 // Constructors have an implicit parameter for the construction phase. |
| 2295 if (method->IsConstructor()) { | 2318 if (method->IsConstructor()) { |
| 2296 method->params.AddFinalParameter( | 2319 method->params.AddFinalParameter( |
| 2297 token_index_, | 2320 TokenIndex(), |
| 2298 kPhaseParameterName, | 2321 kPhaseParameterName, |
| 2299 &Type::ZoneHandle(Type::DynamicType())); | 2322 &Type::ZoneHandle(Type::DynamicType())); |
| 2300 } | 2323 } |
| 2301 if (are_implicitly_final) { | 2324 if (are_implicitly_final) { |
| 2302 method->params.SetImplicitlyFinal(); | 2325 method->params.SetImplicitlyFinal(); |
| 2303 } | 2326 } |
| 2304 ParseFormalParameterList(allow_explicit_default_values, &method->params); | 2327 ParseFormalParameterList(allow_explicit_default_values, &method->params); |
| 2305 if (method->IsGetter() || method->IsSetter()) { | 2328 if (method->IsGetter() || method->IsSetter()) { |
| 2306 int expected_num_parameters = 0; | 2329 int expected_num_parameters = 0; |
| 2307 if (method->IsGetter()) { | 2330 if (method->IsGetter()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2376 ErrorMsg(method->name_pos, | 2399 ErrorMsg(method->name_pos, |
| 2377 "function body not allowed in interface declaration"); | 2400 "function body not allowed in interface declaration"); |
| 2378 } | 2401 } |
| 2379 if (CurrentToken() == Token::kLBRACE) { | 2402 if (CurrentToken() == Token::kLBRACE) { |
| 2380 SkipBlock(); | 2403 SkipBlock(); |
| 2381 } else { | 2404 } else { |
| 2382 ConsumeToken(); | 2405 ConsumeToken(); |
| 2383 SkipExpr(); | 2406 SkipExpr(); |
| 2384 ExpectSemicolon(); | 2407 ExpectSemicolon(); |
| 2385 } | 2408 } |
| 2386 method_end_pos = token_index_; | 2409 method_end_pos = TokenIndex(); |
| 2387 } else if (IsLiteral("native")) { | 2410 } else if (IsLiteral("native")) { |
| 2388 if (method->has_abstract) { | 2411 if (method->has_abstract) { |
| 2389 ErrorMsg(method->name_pos, | 2412 ErrorMsg(method->name_pos, |
| 2390 "abstract method '%s' may not have function body", | 2413 "abstract method '%s' may not have function body", |
| 2391 method->name->ToCString()); | 2414 method->name->ToCString()); |
| 2392 } else if (members->is_interface()) { | 2415 } else if (members->is_interface()) { |
| 2393 ErrorMsg(method->name_pos, | 2416 ErrorMsg(method->name_pos, |
| 2394 "function body not allowed in interface declaration"); | 2417 "function body not allowed in interface declaration"); |
| 2395 } else if (method->IsConstructor() && method->has_const) { | 2418 } else if (method->IsConstructor() && method->has_const) { |
| 2396 ErrorMsg(method->name_pos, | 2419 ErrorMsg(method->name_pos, |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2516 members->AddFunction(getter); | 2539 members->AddFunction(getter); |
| 2517 } | 2540 } |
| 2518 | 2541 |
| 2519 // For instance fields, we create implicit getter and setter methods. | 2542 // For instance fields, we create implicit getter and setter methods. |
| 2520 if (!field->has_static) { | 2543 if (!field->has_static) { |
| 2521 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); | 2544 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
| 2522 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 2545 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
| 2523 field->has_static, field->has_final, | 2546 field->has_static, field->has_final, |
| 2524 field->name_pos); | 2547 field->name_pos); |
| 2525 ParamList params; | 2548 ParamList params; |
| 2526 params.AddReceiver(token_index_); | 2549 params.AddReceiver(TokenIndex()); |
| 2527 getter.set_result_type(*field->type); | 2550 getter.set_result_type(*field->type); |
| 2528 AddFormalParamsToFunction(¶ms, getter); | 2551 AddFormalParamsToFunction(¶ms, getter); |
| 2529 members->AddFunction(getter); | 2552 members->AddFunction(getter); |
| 2530 if (!field->has_final) { | 2553 if (!field->has_final) { |
| 2531 // Build a setter accessor for non-const fields. | 2554 // Build a setter accessor for non-const fields. |
| 2532 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); | 2555 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); |
| 2533 setter = Function::New(setter_name, RawFunction::kImplicitSetter, | 2556 setter = Function::New(setter_name, RawFunction::kImplicitSetter, |
| 2534 field->has_static, field->has_final, | 2557 field->has_static, field->has_final, |
| 2535 field->name_pos); | 2558 field->name_pos); |
| 2536 ParamList params; | 2559 ParamList params; |
| 2537 params.AddReceiver(token_index_); | 2560 params.AddReceiver(TokenIndex()); |
| 2538 params.AddFinalParameter(token_index_, "value", field->type); | 2561 params.AddFinalParameter(TokenIndex(), "value", field->type); |
| 2539 setter.set_result_type(Type::Handle(Type::VoidType())); | 2562 setter.set_result_type(Type::Handle(Type::VoidType())); |
| 2540 AddFormalParamsToFunction(¶ms, setter); | 2563 AddFormalParamsToFunction(¶ms, setter); |
| 2541 members->AddFunction(setter); | 2564 members->AddFunction(setter); |
| 2542 } | 2565 } |
| 2543 } | 2566 } |
| 2544 | 2567 |
| 2545 if (CurrentToken() != Token::kCOMMA) { | 2568 if (CurrentToken() != Token::kCOMMA) { |
| 2546 break; | 2569 break; |
| 2547 } | 2570 } |
| 2548 ConsumeToken(); | 2571 ConsumeToken(); |
| 2549 field->name_pos = this->token_index_; | 2572 field->name_pos = this->TokenIndex(); |
| 2550 field->name = ExpectIdentifier("field name expected"); | 2573 field->name = ExpectIdentifier("field name expected"); |
| 2551 } | 2574 } |
| 2552 ExpectSemicolon(); | 2575 ExpectSemicolon(); |
| 2553 } | 2576 } |
| 2554 | 2577 |
| 2555 | 2578 |
| 2556 void Parser::CheckOperatorArity( | 2579 void Parser::CheckOperatorArity( |
| 2557 const MemberDesc& member, Token::Kind operator_token) { | 2580 const MemberDesc& member, Token::Kind operator_token) { |
| 2558 intptr_t expected_num_parameters; // Includes receiver. | 2581 intptr_t expected_num_parameters; // Includes receiver. |
| 2559 if (operator_token == Token::kASSIGN_INDEX) { | 2582 if (operator_token == Token::kASSIGN_INDEX) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2661 } | 2684 } |
| 2662 const Object& result_type_class = Object::Handle( | 2685 const Object& result_type_class = Object::Handle( |
| 2663 UnresolvedClass::New(lib_prefix, | 2686 UnresolvedClass::New(lib_prefix, |
| 2664 *factory_name.ident, | 2687 *factory_name.ident, |
| 2665 factory_name.ident_pos)); | 2688 factory_name.ident_pos)); |
| 2666 // The type arguments of the result type are set during finalization. | 2689 // The type arguments of the result type are set during finalization. |
| 2667 member.type = &Type::ZoneHandle(Type::New(result_type_class, | 2690 member.type = &Type::ZoneHandle(Type::New(result_type_class, |
| 2668 TypeArguments::Handle(), | 2691 TypeArguments::Handle(), |
| 2669 factory_name.ident_pos)); | 2692 factory_name.ident_pos)); |
| 2670 } else { | 2693 } else { |
| 2671 member.name_pos = token_index_; | 2694 member.name_pos = TokenIndex(); |
| 2672 member.name = CurrentLiteral(); | 2695 member.name = CurrentLiteral(); |
| 2673 ConsumeToken(); | 2696 ConsumeToken(); |
| 2674 } | 2697 } |
| 2675 // We must be dealing with a constructor or named constructor. | 2698 // We must be dealing with a constructor or named constructor. |
| 2676 member.kind = RawFunction::kConstructor; | 2699 member.kind = RawFunction::kConstructor; |
| 2677 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); | 2700 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); |
| 2678 if (CurrentToken() == Token::kPERIOD) { | 2701 if (CurrentToken() == Token::kPERIOD) { |
| 2679 // Named constructor. | 2702 // Named constructor. |
| 2680 ConsumeToken(); | 2703 ConsumeToken(); |
| 2681 const String* name = ExpectIdentifier("identifier expected"); | 2704 const String* name = ExpectIdentifier("identifier expected"); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2699 if (CurrentToken() != Token::kLPAREN) { | 2722 if (CurrentToken() != Token::kLPAREN) { |
| 2700 ErrorMsg("left parenthesis expected"); | 2723 ErrorMsg("left parenthesis expected"); |
| 2701 } | 2724 } |
| 2702 } else if ((CurrentToken() == Token::kGET) && !member.has_var && | 2725 } else if ((CurrentToken() == Token::kGET) && !member.has_var && |
| 2703 (LookaheadToken(1) != Token::kLPAREN) && | 2726 (LookaheadToken(1) != Token::kLPAREN) && |
| 2704 (LookaheadToken(1) != Token::kASSIGN) && | 2727 (LookaheadToken(1) != Token::kASSIGN) && |
| 2705 (LookaheadToken(1) != Token::kCOMMA) && | 2728 (LookaheadToken(1) != Token::kCOMMA) && |
| 2706 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2729 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 2707 ConsumeToken(); | 2730 ConsumeToken(); |
| 2708 member.kind = RawFunction::kGetterFunction; | 2731 member.kind = RawFunction::kGetterFunction; |
| 2709 member.name_pos = this->token_index_; | 2732 member.name_pos = this->TokenIndex(); |
| 2710 member.name = ExpectIdentifier("identifier expected"); | 2733 member.name = ExpectIdentifier("identifier expected"); |
| 2711 if (CurrentToken() != Token::kLPAREN) { | 2734 if (CurrentToken() != Token::kLPAREN) { |
| 2712 ErrorMsg("'(' expected"); | 2735 ErrorMsg("'(' expected"); |
| 2713 } | 2736 } |
| 2714 // If the result type was not specified, it will be set to DynamicType. | 2737 // If the result type was not specified, it will be set to DynamicType. |
| 2715 } else if ((CurrentToken() == Token::kSET) && !member.has_var && | 2738 } else if ((CurrentToken() == Token::kSET) && !member.has_var && |
| 2716 (LookaheadToken(1) != Token::kLPAREN) && | 2739 (LookaheadToken(1) != Token::kLPAREN) && |
| 2717 (LookaheadToken(1) != Token::kASSIGN) && | 2740 (LookaheadToken(1) != Token::kASSIGN) && |
| 2718 (LookaheadToken(1) != Token::kCOMMA) && | 2741 (LookaheadToken(1) != Token::kCOMMA) && |
| 2719 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2742 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 2720 ConsumeToken(); | 2743 ConsumeToken(); |
| 2721 member.kind = RawFunction::kSetterFunction; | 2744 member.kind = RawFunction::kSetterFunction; |
| 2722 member.name_pos = this->token_index_; | 2745 member.name_pos = this->TokenIndex(); |
| 2723 member.name = ExpectIdentifier("identifier expected"); | 2746 member.name = ExpectIdentifier("identifier expected"); |
| 2724 if (CurrentToken() != Token::kLPAREN) { | 2747 if (CurrentToken() != Token::kLPAREN) { |
| 2725 ErrorMsg("'(' expected"); | 2748 ErrorMsg("'(' expected"); |
| 2726 } | 2749 } |
| 2727 // The grammar allows a return type, so member.type is not always NULL here. | 2750 // The grammar allows a return type, so member.type is not always NULL here. |
| 2728 // If no return type is specified, the return type of the setter is Dynamic. | 2751 // If no return type is specified, the return type of the setter is Dynamic. |
| 2729 if (member.type == NULL) { | 2752 if (member.type == NULL) { |
| 2730 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2753 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2731 } | 2754 } |
| 2732 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && | 2755 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && |
| 2733 (LookaheadToken(1) != Token::kLPAREN) && | 2756 (LookaheadToken(1) != Token::kLPAREN) && |
| 2734 (LookaheadToken(1) != Token::kASSIGN) && | 2757 (LookaheadToken(1) != Token::kASSIGN) && |
| 2735 (LookaheadToken(1) != Token::kCOMMA) && | 2758 (LookaheadToken(1) != Token::kCOMMA) && |
| 2736 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2759 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 2737 ConsumeToken(); | 2760 ConsumeToken(); |
| 2738 if (!Token::CanBeOverloaded(CurrentToken())) { | 2761 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 2739 ErrorMsg("invalid operator overloading"); | 2762 ErrorMsg("invalid operator overloading"); |
| 2740 } | 2763 } |
| 2741 if (member.has_static) { | 2764 if (member.has_static) { |
| 2742 ErrorMsg("operator overloading functions cannot be static"); | 2765 ErrorMsg("operator overloading functions cannot be static"); |
| 2743 } | 2766 } |
| 2744 operator_token = CurrentToken(); | 2767 operator_token = CurrentToken(); |
| 2745 member.kind = RawFunction::kFunction; | 2768 member.kind = RawFunction::kFunction; |
| 2746 member.name_pos = this->token_index_; | 2769 member.name_pos = this->TokenIndex(); |
| 2747 member.name = | 2770 member.name = |
| 2748 &String::ZoneHandle(String::NewSymbol(Token::Str(operator_token))); | 2771 &String::ZoneHandle(String::NewSymbol(Token::Str(operator_token))); |
| 2749 ConsumeToken(); | 2772 ConsumeToken(); |
| 2750 } else if (IsIdentifier()) { | 2773 } else if (IsIdentifier()) { |
| 2751 member.name = CurrentLiteral(); | 2774 member.name = CurrentLiteral(); |
| 2752 member.name_pos = token_index_; | 2775 member.name_pos = TokenIndex(); |
| 2753 ConsumeToken(); | 2776 ConsumeToken(); |
| 2754 } else { | 2777 } else { |
| 2755 ErrorMsg("identifier expected"); | 2778 ErrorMsg("identifier expected"); |
| 2756 } | 2779 } |
| 2757 | 2780 |
| 2758 ASSERT(member.name != NULL); | 2781 ASSERT(member.name != NULL); |
| 2759 if (CurrentToken() == Token::kLPAREN) { | 2782 if (CurrentToken() == Token::kLPAREN) { |
| 2760 if (members->is_interface() && member.has_static) { | 2783 if (members->is_interface() && member.has_static) { |
| 2761 if (member.has_factory) { | 2784 if (member.has_factory) { |
| 2762 ErrorMsg("factory constructors are not allowed in interfaces"); | 2785 ErrorMsg("factory constructors are not allowed in interfaces"); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2790 } else { | 2813 } else { |
| 2791 UnexpectedToken(); | 2814 UnexpectedToken(); |
| 2792 } | 2815 } |
| 2793 current_member_ = NULL; | 2816 current_member_ = NULL; |
| 2794 members->AddMember(member); | 2817 members->AddMember(member); |
| 2795 } | 2818 } |
| 2796 | 2819 |
| 2797 | 2820 |
| 2798 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { | 2821 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { |
| 2799 TRACE_PARSER("ParseClassDefinition"); | 2822 TRACE_PARSER("ParseClassDefinition"); |
| 2800 const intptr_t class_pos = token_index_; | 2823 const intptr_t class_pos = TokenIndex(); |
| 2801 ExpectToken(Token::kCLASS); | 2824 ExpectToken(Token::kCLASS); |
| 2802 const intptr_t classname_pos = token_index_; | 2825 const intptr_t classname_pos = TokenIndex(); |
| 2803 String& class_name = *ExpectTypeIdentifier("class name expected"); | 2826 String& class_name = *ExpectTypeIdentifier("class name expected"); |
| 2804 if (FLAG_trace_parser) { | 2827 if (FLAG_trace_parser) { |
| 2805 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 2828 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 2806 } | 2829 } |
| 2807 Class& cls = Class::Handle(); | 2830 Class& cls = Class::Handle(); |
| 2808 Object& obj = Object::Handle(library_.LookupObject(class_name)); | 2831 Object& obj = Object::Handle(library_.LookupObject(class_name)); |
| 2809 if (obj.IsNull()) { | 2832 if (obj.IsNull()) { |
| 2810 cls = Class::New(class_name, script_, classname_pos); | 2833 cls = Class::New(class_name, script_, classname_pos); |
| 2811 library_.AddClass(cls); | 2834 library_.AddClass(cls); |
| 2812 } else { | 2835 } else { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2823 class_name.ToCString()); | 2846 class_name.ToCString()); |
| 2824 } | 2847 } |
| 2825 } | 2848 } |
| 2826 ASSERT(!cls.IsNull()); | 2849 ASSERT(!cls.IsNull()); |
| 2827 ASSERT(cls.functions() == Array::Empty()); | 2850 ASSERT(cls.functions() == Array::Empty()); |
| 2828 set_current_class(cls); | 2851 set_current_class(cls); |
| 2829 ParseTypeParameters(cls); | 2852 ParseTypeParameters(cls); |
| 2830 Type& super_type = Type::Handle(); | 2853 Type& super_type = Type::Handle(); |
| 2831 if (CurrentToken() == Token::kEXTENDS) { | 2854 if (CurrentToken() == Token::kEXTENDS) { |
| 2832 ConsumeToken(); | 2855 ConsumeToken(); |
| 2833 const intptr_t type_pos = token_index_; | 2856 const intptr_t type_pos = TokenIndex(); |
| 2834 const AbstractType& type = AbstractType::Handle( | 2857 const AbstractType& type = AbstractType::Handle( |
| 2835 ParseType(ClassFinalizer::kTryResolve)); | 2858 ParseType(ClassFinalizer::kTryResolve)); |
| 2836 if (type.IsTypeParameter()) { | 2859 if (type.IsTypeParameter()) { |
| 2837 ErrorMsg(type_pos, | 2860 ErrorMsg(type_pos, |
| 2838 "class '%s' may not extend type parameter '%s'", | 2861 "class '%s' may not extend type parameter '%s'", |
| 2839 class_name.ToCString(), | 2862 class_name.ToCString(), |
| 2840 String::Handle(type.Name()).ToCString()); | 2863 String::Handle(type.Name()).ToCString()); |
| 2841 } | 2864 } |
| 2842 super_type ^= type.raw(); | 2865 super_type ^= type.raw(); |
| 2843 if (super_type.IsInterfaceType()) { | 2866 if (super_type.IsInterfaceType()) { |
| 2844 ErrorMsg(type_pos, | 2867 ErrorMsg(type_pos, |
| 2845 "class '%s' may implement, but cannot extend interface '%s'", | 2868 "class '%s' may implement, but cannot extend interface '%s'", |
| 2846 class_name.ToCString(), | 2869 class_name.ToCString(), |
| 2847 String::Handle(super_type.Name()).ToCString()); | 2870 String::Handle(super_type.Name()).ToCString()); |
| 2848 } | 2871 } |
| 2849 } else { | 2872 } else { |
| 2850 // No extends clause: Implicitly extend Object. | 2873 // No extends clause: Implicitly extend Object. |
| 2851 super_type = Type::ObjectType(); | 2874 super_type = Type::ObjectType(); |
| 2852 } | 2875 } |
| 2853 ASSERT(!super_type.IsNull()); | 2876 ASSERT(!super_type.IsNull()); |
| 2854 cls.set_super_type(super_type); | 2877 cls.set_super_type(super_type); |
| 2855 | 2878 |
| 2856 if (CurrentToken() == Token::kIMPLEMENTS) { | 2879 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 2857 Array& interfaces = Array::Handle(); | 2880 Array& interfaces = Array::Handle(); |
| 2858 const intptr_t interfaces_pos = token_index_; | 2881 const intptr_t interfaces_pos = TokenIndex(); |
| 2859 interfaces = ParseInterfaceList(); | 2882 interfaces = ParseInterfaceList(); |
| 2860 AddInterfaces(interfaces_pos, cls, interfaces); | 2883 AddInterfaces(interfaces_pos, cls, interfaces); |
| 2861 } | 2884 } |
| 2862 | 2885 |
| 2863 ExpectToken(Token::kLBRACE); | 2886 ExpectToken(Token::kLBRACE); |
| 2864 ClassDesc members(cls, class_name, false, class_pos); | 2887 ClassDesc members(cls, class_name, false, class_pos); |
| 2865 while (CurrentToken() != Token::kRBRACE) { | 2888 while (CurrentToken() != Token::kRBRACE) { |
| 2866 ParseClassMemberDefinition(&members); | 2889 ParseClassMemberDefinition(&members); |
| 2867 } | 2890 } |
| 2868 ExpectToken(Token::kRBRACE); | 2891 ExpectToken(Token::kRBRACE); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2895 // The token position for the implicit constructor is the 'class' | 2918 // The token position for the implicit constructor is the 'class' |
| 2896 // keyword of the constructor's class. | 2919 // keyword of the constructor's class. |
| 2897 Function& ctor = Function::Handle( | 2920 Function& ctor = Function::Handle( |
| 2898 Function::New(ctor_name, | 2921 Function::New(ctor_name, |
| 2899 RawFunction::kConstructor, | 2922 RawFunction::kConstructor, |
| 2900 /* is_static = */ false, | 2923 /* is_static = */ false, |
| 2901 /* is_const = */ false, | 2924 /* is_const = */ false, |
| 2902 class_desc->token_pos())); | 2925 class_desc->token_pos())); |
| 2903 ParamList params; | 2926 ParamList params; |
| 2904 // Add implicit 'this' parameter. | 2927 // Add implicit 'this' parameter. |
| 2905 params.AddReceiver(token_index_); | 2928 params.AddReceiver(TokenIndex()); |
| 2906 // Add implicit parameter for construction phase. | 2929 // Add implicit parameter for construction phase. |
| 2907 params.AddFinalParameter( | 2930 params.AddFinalParameter( |
| 2908 token_index_, | 2931 TokenIndex(), |
| 2909 kPhaseParameterName, | 2932 kPhaseParameterName, |
| 2910 &Type::ZoneHandle(Type::DynamicType())); | 2933 &Type::ZoneHandle(Type::DynamicType())); |
| 2911 | 2934 |
| 2912 AddFormalParamsToFunction(¶ms, ctor); | 2935 AddFormalParamsToFunction(¶ms, ctor); |
| 2913 // The body of the constructor cannot modify the type arguments of the | 2936 // The body of the constructor cannot modify the type arguments of the |
| 2914 // constructed instance, which is passed in as a hidden parameter. | 2937 // constructed instance, which is passed in as a hidden parameter. |
| 2915 // Therefore, there is no need to set the result type to be checked. | 2938 // Therefore, there is no need to set the result type to be checked. |
| 2916 const AbstractType& result_type = Type::ZoneHandle(Type::DynamicType()); | 2939 const AbstractType& result_type = Type::ZoneHandle(Type::DynamicType()); |
| 2917 ctor.set_result_type(result_type); | 2940 ctor.set_result_type(result_type); |
| 2918 class_desc->AddFunction(ctor); | 2941 class_desc->AddFunction(ctor); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2945 | 2968 |
| 2946 | 2969 |
| 2947 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 2970 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 2948 // We need this lookahead to distinguish between the optional return type | 2971 // We need this lookahead to distinguish between the optional return type |
| 2949 // and the alias name of a function type alias. | 2972 // and the alias name of a function type alias. |
| 2950 // Token position remains unchanged. | 2973 // Token position remains unchanged. |
| 2951 bool Parser::IsFunctionTypeAliasName() { | 2974 bool Parser::IsFunctionTypeAliasName() { |
| 2952 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 2975 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 2953 return true; | 2976 return true; |
| 2954 } | 2977 } |
| 2955 const intptr_t saved_pos = token_index_; | 2978 const intptr_t saved_pos = TokenIndex(); |
| 2956 bool is_alias_name = false; | 2979 bool is_alias_name = false; |
| 2957 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 2980 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 2958 ConsumeToken(); | 2981 ConsumeToken(); |
| 2959 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 2982 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
| 2960 is_alias_name = true; | 2983 is_alias_name = true; |
| 2961 } | 2984 } |
| 2962 } | 2985 } |
| 2963 SetPosition(saved_pos); | 2986 SetPosition(saved_pos); |
| 2964 return is_alias_name; | 2987 return is_alias_name; |
| 2965 } | 2988 } |
| 2966 | 2989 |
| 2967 | 2990 |
| 2968 void Parser::ParseFunctionTypeAlias( | 2991 void Parser::ParseFunctionTypeAlias( |
| 2969 const GrowableObjectArray& pending_classes) { | 2992 const GrowableObjectArray& pending_classes) { |
| 2970 TRACE_PARSER("ParseFunctionTypeAlias"); | 2993 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 2971 ExpectToken(Token::kTYPEDEF); | 2994 ExpectToken(Token::kTYPEDEF); |
| 2972 | 2995 |
| 2973 // Allocate an interface to hold the type parameters and their bounds. | 2996 // Allocate an interface to hold the type parameters and their bounds. |
| 2974 // Make it the owner of the function type descriptor. | 2997 // Make it the owner of the function type descriptor. |
| 2975 const Class& alias_owner = Class::Handle( | 2998 const Class& alias_owner = Class::Handle( |
| 2976 Class::New(String::Handle(String::NewSymbol(":alias_owner")), | 2999 Class::New(String::Handle(String::NewSymbol(":alias_owner")), |
| 2977 Script::Handle(), | 3000 Script::Handle(), |
| 2978 token_index_)); | 3001 TokenIndex())); |
| 2979 alias_owner.set_is_interface(); | 3002 alias_owner.set_is_interface(); |
| 2980 alias_owner.set_library(library_); | 3003 alias_owner.set_library(library_); |
| 2981 set_current_class(alias_owner); | 3004 set_current_class(alias_owner); |
| 2982 | 3005 |
| 2983 // Parse the result type of the function type. | 3006 // Parse the result type of the function type. |
| 2984 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3007 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 2985 if (CurrentToken() == Token::kVOID) { | 3008 if (CurrentToken() == Token::kVOID) { |
| 2986 ConsumeToken(); | 3009 ConsumeToken(); |
| 2987 result_type = Type::VoidType(); | 3010 result_type = Type::VoidType(); |
| 2988 } else if (!IsFunctionTypeAliasName()) { | 3011 } else if (!IsFunctionTypeAliasName()) { |
| 2989 // Type annotations in typedef are never ignored, even in unchecked mode. | 3012 // Type annotations in typedef are never ignored, even in unchecked mode. |
| 2990 // Wait until we have an owner class before resolving the result type. | 3013 // Wait until we have an owner class before resolving the result type. |
| 2991 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 3014 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 2992 } | 3015 } |
| 2993 | 3016 |
| 2994 const intptr_t alias_name_pos = token_index_; | 3017 const intptr_t alias_name_pos = TokenIndex(); |
| 2995 const String* alias_name = | 3018 const String* alias_name = |
| 2996 ExpectTypeIdentifier("function alias name expected"); | 3019 ExpectTypeIdentifier("function alias name expected"); |
| 2997 | 3020 |
| 2998 // Parse the type parameters of the function type. | 3021 // Parse the type parameters of the function type. |
| 2999 ParseTypeParameters(alias_owner); | 3022 ParseTypeParameters(alias_owner); |
| 3000 // At this point, the type parameters have been parsed, so we can resolve the | 3023 // At this point, the type parameters have been parsed, so we can resolve the |
| 3001 // result type. | 3024 // result type. |
| 3002 if (!result_type.IsNull()) { | 3025 if (!result_type.IsNull()) { |
| 3003 ResolveTypeFromClass(alias_owner, | 3026 ResolveTypeFromClass(alias_owner, |
| 3004 ClassFinalizer::kTryResolve, | 3027 ClassFinalizer::kTryResolve, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3063 ASSERT(!function_type_alias.is_finalized()); | 3086 ASSERT(!function_type_alias.is_finalized()); |
| 3064 library_.AddClass(function_type_alias); | 3087 library_.AddClass(function_type_alias); |
| 3065 ExpectSemicolon(); | 3088 ExpectSemicolon(); |
| 3066 pending_classes.Add(function_type_alias, Heap::kOld); | 3089 pending_classes.Add(function_type_alias, Heap::kOld); |
| 3067 } | 3090 } |
| 3068 | 3091 |
| 3069 | 3092 |
| 3070 void Parser::ParseInterfaceDefinition( | 3093 void Parser::ParseInterfaceDefinition( |
| 3071 const GrowableObjectArray& pending_classes) { | 3094 const GrowableObjectArray& pending_classes) { |
| 3072 TRACE_PARSER("ParseInterfaceDefinition"); | 3095 TRACE_PARSER("ParseInterfaceDefinition"); |
| 3073 const intptr_t interface_pos = token_index_; | 3096 const intptr_t interface_pos = TokenIndex(); |
| 3074 ExpectToken(Token::kINTERFACE); | 3097 ExpectToken(Token::kINTERFACE); |
| 3075 const intptr_t interfacename_pos = token_index_; | 3098 const intptr_t interfacename_pos = TokenIndex(); |
| 3076 String& interface_name = *ExpectTypeIdentifier("interface name expected"); | 3099 String& interface_name = *ExpectTypeIdentifier("interface name expected"); |
| 3077 if (FLAG_trace_parser) { | 3100 if (FLAG_trace_parser) { |
| 3078 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | 3101 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); |
| 3079 } | 3102 } |
| 3080 Class& interface = Class::Handle(); | 3103 Class& interface = Class::Handle(); |
| 3081 Object& obj = Object::Handle(library_.LookupObject(interface_name)); | 3104 Object& obj = Object::Handle(library_.LookupObject(interface_name)); |
| 3082 if (obj.IsNull()) { | 3105 if (obj.IsNull()) { |
| 3083 interface = Class::NewInterface(interface_name, script_, interfacename_pos); | 3106 interface = Class::NewInterface(interface_name, script_, interfacename_pos); |
| 3084 library_.AddClass(interface); | 3107 library_.AddClass(interface); |
| 3085 } else { | 3108 } else { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 3098 interface_name.ToCString()); | 3121 interface_name.ToCString()); |
| 3099 } | 3122 } |
| 3100 } | 3123 } |
| 3101 ASSERT(!interface.IsNull()); | 3124 ASSERT(!interface.IsNull()); |
| 3102 ASSERT(interface.functions() == Array::Empty()); | 3125 ASSERT(interface.functions() == Array::Empty()); |
| 3103 set_current_class(interface); | 3126 set_current_class(interface); |
| 3104 ParseTypeParameters(interface); | 3127 ParseTypeParameters(interface); |
| 3105 | 3128 |
| 3106 if (CurrentToken() == Token::kEXTENDS) { | 3129 if (CurrentToken() == Token::kEXTENDS) { |
| 3107 Array& interfaces = Array::Handle(); | 3130 Array& interfaces = Array::Handle(); |
| 3108 const intptr_t interfaces_pos = token_index_; | 3131 const intptr_t interfaces_pos = TokenIndex(); |
| 3109 interfaces = ParseInterfaceList(); | 3132 interfaces = ParseInterfaceList(); |
| 3110 AddInterfaces(interfaces_pos, interface, interfaces); | 3133 AddInterfaces(interfaces_pos, interface, interfaces); |
| 3111 } | 3134 } |
| 3112 | 3135 |
| 3113 if (CurrentToken() == Token::kDEFAULT) { | 3136 if (CurrentToken() == Token::kDEFAULT) { |
| 3114 ConsumeToken(); | 3137 ConsumeToken(); |
| 3115 if (CurrentToken() != Token::kIDENT) { | 3138 if (CurrentToken() != Token::kIDENT) { |
| 3116 ErrorMsg("class name expected"); | 3139 ErrorMsg("class name expected"); |
| 3117 } | 3140 } |
| 3118 QualIdent factory_name; | 3141 QualIdent factory_name; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3239 AbstractType& bound = Type::Handle(); | 3262 AbstractType& bound = Type::Handle(); |
| 3240 do { | 3263 do { |
| 3241 ConsumeToken(); | 3264 ConsumeToken(); |
| 3242 if (CurrentToken() != Token::kIDENT) { | 3265 if (CurrentToken() != Token::kIDENT) { |
| 3243 ErrorMsg("type parameter name expected"); | 3266 ErrorMsg("type parameter name expected"); |
| 3244 } | 3267 } |
| 3245 String& type_parameter_name = *CurrentLiteral(); | 3268 String& type_parameter_name = *CurrentLiteral(); |
| 3246 type_parameter = TypeParameter::New(cls, | 3269 type_parameter = TypeParameter::New(cls, |
| 3247 index, | 3270 index, |
| 3248 type_parameter_name, | 3271 type_parameter_name, |
| 3249 token_index_); | 3272 TokenIndex()); |
| 3250 // Check for duplicate type parameters. | 3273 // Check for duplicate type parameters. |
| 3251 for (intptr_t i = 0; i < index; i++) { | 3274 for (intptr_t i = 0; i < index; i++) { |
| 3252 existing_type_parameter ^= type_parameters_array.At(i); | 3275 existing_type_parameter ^= type_parameters_array.At(i); |
| 3253 existing_type_parameter_name = existing_type_parameter.Name(); | 3276 existing_type_parameter_name = existing_type_parameter.Name(); |
| 3254 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 3277 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| 3255 ErrorMsg("duplicate type parameter '%s'", | 3278 ErrorMsg("duplicate type parameter '%s'", |
| 3256 type_parameter_name.ToCString()); | 3279 type_parameter_name.ToCString()); |
| 3257 } | 3280 } |
| 3258 } | 3281 } |
| 3259 ConsumeToken(); | 3282 ConsumeToken(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3336 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 3359 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || |
| 3337 (CurrentToken() == Token::kEXTENDS)); | 3360 (CurrentToken() == Token::kEXTENDS)); |
| 3338 const GrowableObjectArray& interfaces = | 3361 const GrowableObjectArray& interfaces = |
| 3339 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3362 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3340 String& interface_name = String::Handle(); | 3363 String& interface_name = String::Handle(); |
| 3341 AbstractType& interface = AbstractType::Handle(); | 3364 AbstractType& interface = AbstractType::Handle(); |
| 3342 String& other_name = String::Handle(); | 3365 String& other_name = String::Handle(); |
| 3343 AbstractType& other_interface = AbstractType::Handle(); | 3366 AbstractType& other_interface = AbstractType::Handle(); |
| 3344 do { | 3367 do { |
| 3345 ConsumeToken(); | 3368 ConsumeToken(); |
| 3346 intptr_t supertype_pos = token_index_; | 3369 intptr_t supertype_pos = TokenIndex(); |
| 3347 interface = ParseType(ClassFinalizer::kTryResolve); | 3370 interface = ParseType(ClassFinalizer::kTryResolve); |
| 3348 interface_name = interface.Name(); | 3371 interface_name = interface.Name(); |
| 3349 for (int i = 0; i < interfaces.Length(); i++) { | 3372 for (int i = 0; i < interfaces.Length(); i++) { |
| 3350 other_interface ^= interfaces.At(i); | 3373 other_interface ^= interfaces.At(i); |
| 3351 other_name = other_interface.Name(); | 3374 other_name = other_interface.Name(); |
| 3352 if (interface_name.Equals(other_name)) { | 3375 if (interface_name.Equals(other_name)) { |
| 3353 ErrorMsg(supertype_pos, "Duplicate supertype '%s'", | 3376 ErrorMsg(supertype_pos, "Duplicate supertype '%s'", |
| 3354 interface_name.ToCString()); | 3377 interface_name.ToCString()); |
| 3355 } | 3378 } |
| 3356 } | 3379 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3408 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3431 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3409 TRACE_PARSER("ParseTopLevelVariable"); | 3432 TRACE_PARSER("ParseTopLevelVariable"); |
| 3410 const bool is_final = (CurrentToken() == Token::kFINAL); | 3433 const bool is_final = (CurrentToken() == Token::kFINAL); |
| 3411 const bool is_static = true; | 3434 const bool is_static = true; |
| 3412 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 3435 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3413 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : | 3436 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : |
| 3414 ClassFinalizer::kIgnore)); | 3437 ClassFinalizer::kIgnore)); |
| 3415 Field& field = Field::Handle(); | 3438 Field& field = Field::Handle(); |
| 3416 Function& getter = Function::Handle(); | 3439 Function& getter = Function::Handle(); |
| 3417 while (true) { | 3440 while (true) { |
| 3418 const intptr_t name_pos = token_index_; | 3441 const intptr_t name_pos = TokenIndex(); |
| 3419 String& var_name = *ExpectIdentifier("variable name expected"); | 3442 String& var_name = *ExpectIdentifier("variable name expected"); |
| 3420 | 3443 |
| 3421 if (library_.LookupObject(var_name) != Object::null()) { | 3444 if (library_.LookupObject(var_name) != Object::null()) { |
| 3422 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 3445 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 3423 } | 3446 } |
| 3424 String& accessor_name = String::Handle(Field::GetterName(var_name)); | 3447 String& accessor_name = String::Handle(Field::GetterName(var_name)); |
| 3425 if (library_.LookupObject(accessor_name) != Object::null()) { | 3448 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3426 ErrorMsg(name_pos, "getter for '%s' is already defined", | 3449 ErrorMsg(name_pos, "getter for '%s' is already defined", |
| 3427 var_name.ToCString()); | 3450 var_name.ToCString()); |
| 3428 } | 3451 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3470 if (CurrentToken() == Token::kVOID) { | 3493 if (CurrentToken() == Token::kVOID) { |
| 3471 ConsumeToken(); | 3494 ConsumeToken(); |
| 3472 result_type = Type::VoidType(); | 3495 result_type = Type::VoidType(); |
| 3473 } else { | 3496 } else { |
| 3474 // Parse optional type. | 3497 // Parse optional type. |
| 3475 if ((CurrentToken() == Token::kIDENT) && | 3498 if ((CurrentToken() == Token::kIDENT) && |
| 3476 (LookaheadToken(1) != Token::kLPAREN)) { | 3499 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3477 result_type = ParseType(ClassFinalizer::kTryResolve); | 3500 result_type = ParseType(ClassFinalizer::kTryResolve); |
| 3478 } | 3501 } |
| 3479 } | 3502 } |
| 3480 const intptr_t name_pos = token_index_; | 3503 const intptr_t name_pos = TokenIndex(); |
| 3481 const String& func_name = *ExpectIdentifier("function name expected"); | 3504 const String& func_name = *ExpectIdentifier("function name expected"); |
| 3482 | 3505 |
| 3483 if (library_.LookupObject(func_name) != Object::null()) { | 3506 if (library_.LookupObject(func_name) != Object::null()) { |
| 3484 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 3507 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 3485 } | 3508 } |
| 3486 String& accessor_name = String::Handle(Field::GetterName(func_name)); | 3509 String& accessor_name = String::Handle(Field::GetterName(func_name)); |
| 3487 if (library_.LookupObject(accessor_name) != Object::null()) { | 3510 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3488 ErrorMsg(name_pos, "'%s' is already defined as getter", | 3511 ErrorMsg(name_pos, "'%s' is already defined as getter", |
| 3489 func_name.ToCString()); | 3512 func_name.ToCString()); |
| 3490 } | 3513 } |
| 3491 accessor_name = Field::SetterName(func_name); | 3514 accessor_name = Field::SetterName(func_name); |
| 3492 if (library_.LookupObject(accessor_name) != Object::null()) { | 3515 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3493 ErrorMsg(name_pos, "'%s' is already defined as setter", | 3516 ErrorMsg(name_pos, "'%s' is already defined as setter", |
| 3494 func_name.ToCString()); | 3517 func_name.ToCString()); |
| 3495 } | 3518 } |
| 3496 | 3519 |
| 3497 if (CurrentToken() != Token::kLPAREN) { | 3520 if (CurrentToken() != Token::kLPAREN) { |
| 3498 ErrorMsg("'(' expected"); | 3521 ErrorMsg("'(' expected"); |
| 3499 } | 3522 } |
| 3500 const intptr_t function_pos = token_index_; | 3523 const intptr_t function_pos = TokenIndex(); |
| 3501 ParamList params; | 3524 ParamList params; |
| 3502 const bool allow_explicit_default_values = true; | 3525 const bool allow_explicit_default_values = true; |
| 3503 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 3526 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 3504 | 3527 |
| 3505 intptr_t function_end_pos = function_pos; | 3528 intptr_t function_end_pos = function_pos; |
| 3506 if (CurrentToken() == Token::kLBRACE) { | 3529 if (CurrentToken() == Token::kLBRACE) { |
| 3507 SkipBlock(); | 3530 SkipBlock(); |
| 3508 function_end_pos = token_index_; | 3531 function_end_pos = TokenIndex(); |
| 3509 } else if (CurrentToken() == Token::kARROW) { | 3532 } else if (CurrentToken() == Token::kARROW) { |
| 3510 ConsumeToken(); | 3533 ConsumeToken(); |
| 3511 SkipExpr(); | 3534 SkipExpr(); |
| 3512 ExpectSemicolon(); | 3535 ExpectSemicolon(); |
| 3513 function_end_pos = token_index_; | 3536 function_end_pos = TokenIndex(); |
| 3514 } else if (IsLiteral("native")) { | 3537 } else if (IsLiteral("native")) { |
| 3515 ParseNativeDeclaration(); | 3538 ParseNativeDeclaration(); |
| 3516 } else { | 3539 } else { |
| 3517 ErrorMsg("function block expected"); | 3540 ErrorMsg("function block expected"); |
| 3518 } | 3541 } |
| 3519 Function& func = Function::Handle( | 3542 Function& func = Function::Handle( |
| 3520 Function::New(func_name, RawFunction::kFunction, | 3543 Function::New(func_name, RawFunction::kFunction, |
| 3521 is_static, false, function_pos)); | 3544 is_static, false, function_pos)); |
| 3522 func.set_result_type(result_type); | 3545 func.set_result_type(result_type); |
| 3523 func.set_end_token_index(function_end_pos); | 3546 func.set_end_token_index(function_end_pos); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 3543 } else { | 3566 } else { |
| 3544 result_type = ParseType(ClassFinalizer::kTryResolve); | 3567 result_type = ParseType(ClassFinalizer::kTryResolve); |
| 3545 } | 3568 } |
| 3546 is_getter = (CurrentToken() == Token::kGET); | 3569 is_getter = (CurrentToken() == Token::kGET); |
| 3547 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 3570 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
| 3548 ConsumeToken(); | 3571 ConsumeToken(); |
| 3549 } else { | 3572 } else { |
| 3550 UnexpectedToken(); | 3573 UnexpectedToken(); |
| 3551 } | 3574 } |
| 3552 } | 3575 } |
| 3553 const intptr_t name_pos = token_index_; | 3576 const intptr_t name_pos = TokenIndex(); |
| 3554 const String* field_name = ExpectIdentifier("accessor name expected"); | 3577 const String* field_name = ExpectIdentifier("accessor name expected"); |
| 3555 | 3578 |
| 3556 if (CurrentToken() != Token::kLPAREN) { | 3579 if (CurrentToken() != Token::kLPAREN) { |
| 3557 ErrorMsg("'(' expected"); | 3580 ErrorMsg("'(' expected"); |
| 3558 } | 3581 } |
| 3559 const intptr_t accessor_pos = token_index_; | 3582 const intptr_t accessor_pos = TokenIndex(); |
| 3560 ParamList params; | 3583 ParamList params; |
| 3561 const bool allow_explicit_default_values = true; | 3584 const bool allow_explicit_default_values = true; |
| 3562 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 3585 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 3563 String& accessor_name = String::ZoneHandle(); | 3586 String& accessor_name = String::ZoneHandle(); |
| 3564 int expected_num_parameters = -1; | 3587 int expected_num_parameters = -1; |
| 3565 if (is_getter) { | 3588 if (is_getter) { |
| 3566 expected_num_parameters = 0; | 3589 expected_num_parameters = 0; |
| 3567 accessor_name = Field::GetterSymbol(*field_name); | 3590 accessor_name = Field::GetterSymbol(*field_name); |
| 3568 } else { | 3591 } else { |
| 3569 expected_num_parameters = 1; | 3592 expected_num_parameters = 1; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3646 prev_error ^= Api::UnwrapHandle(result); | 3669 prev_error ^= Api::UnwrapHandle(result); |
| 3647 AppendErrorMsg(prev_error, token_pos, "library handler failed"); | 3670 AppendErrorMsg(prev_error, token_pos, "library handler failed"); |
| 3648 } | 3671 } |
| 3649 return result; | 3672 return result; |
| 3650 } | 3673 } |
| 3651 | 3674 |
| 3652 | 3675 |
| 3653 void Parser::ParseLibraryImport() { | 3676 void Parser::ParseLibraryImport() { |
| 3654 TRACE_PARSER("ParseLibraryImport"); | 3677 TRACE_PARSER("ParseLibraryImport"); |
| 3655 while (CurrentToken() == Token::kIMPORT) { | 3678 while (CurrentToken() == Token::kIMPORT) { |
| 3656 const intptr_t import_pos = token_index_; | 3679 const intptr_t import_pos = TokenIndex(); |
| 3657 ConsumeToken(); | 3680 ConsumeToken(); |
| 3658 ExpectToken(Token::kLPAREN); | 3681 ExpectToken(Token::kLPAREN); |
| 3659 if (CurrentToken() != Token::kSTRING) { | 3682 if (CurrentToken() != Token::kSTRING) { |
| 3660 ErrorMsg("library url expected"); | 3683 ErrorMsg("library url expected"); |
| 3661 } | 3684 } |
| 3662 const String& url = *ParseImportStringLiteral(); | 3685 const String& url = *ParseImportStringLiteral(); |
| 3663 String& prefix = String::Handle(); | 3686 String& prefix = String::Handle(); |
| 3664 if (CurrentToken() == Token::kCOMMA) { | 3687 if (CurrentToken() == Token::kCOMMA) { |
| 3665 ConsumeToken(); | 3688 ConsumeToken(); |
| 3666 if (!IsLiteral("prefix")) { | 3689 if (!IsLiteral("prefix")) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3710 library_.AddObject(library_prefix, prefix); | 3733 library_.AddObject(library_prefix, prefix); |
| 3711 } | 3734 } |
| 3712 } | 3735 } |
| 3713 } | 3736 } |
| 3714 } | 3737 } |
| 3715 | 3738 |
| 3716 | 3739 |
| 3717 void Parser::ParseLibraryInclude() { | 3740 void Parser::ParseLibraryInclude() { |
| 3718 TRACE_PARSER("ParseLibraryInclude"); | 3741 TRACE_PARSER("ParseLibraryInclude"); |
| 3719 while (CurrentToken() == Token::kSOURCE) { | 3742 while (CurrentToken() == Token::kSOURCE) { |
| 3720 const intptr_t source_pos = token_index_; | 3743 const intptr_t source_pos = TokenIndex(); |
| 3721 ConsumeToken(); | 3744 ConsumeToken(); |
| 3722 ExpectToken(Token::kLPAREN); | 3745 ExpectToken(Token::kLPAREN); |
| 3723 if (CurrentToken() != Token::kSTRING) { | 3746 if (CurrentToken() != Token::kSTRING) { |
| 3724 ErrorMsg("source url expected"); | 3747 ErrorMsg("source url expected"); |
| 3725 } | 3748 } |
| 3726 const String& url = *ParseImportStringLiteral(); | 3749 const String& url = *ParseImportStringLiteral(); |
| 3727 ExpectToken(Token::kRPAREN); | 3750 ExpectToken(Token::kRPAREN); |
| 3728 ExpectToken(Token::kSEMICOLON); | 3751 ExpectToken(Token::kSEMICOLON); |
| 3729 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, | 3752 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, |
| 3730 source_pos, | 3753 source_pos, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3775 Isolate* isolate = Isolate::Current(); | 3798 Isolate* isolate = Isolate::Current(); |
| 3776 ObjectStore* object_store = isolate->object_store(); | 3799 ObjectStore* object_store = isolate->object_store(); |
| 3777 const GrowableObjectArray& pending_classes = | 3800 const GrowableObjectArray& pending_classes = |
| 3778 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); | 3801 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); |
| 3779 SetPosition(0); | 3802 SetPosition(0); |
| 3780 is_top_level_ = true; | 3803 is_top_level_ = true; |
| 3781 TopLevel top_level; | 3804 TopLevel top_level; |
| 3782 Class& toplevel_class = Class::Handle( | 3805 Class& toplevel_class = Class::Handle( |
| 3783 Class::New(String::ZoneHandle(String::NewSymbol("::")), | 3806 Class::New(String::ZoneHandle(String::NewSymbol("::")), |
| 3784 script_, | 3807 script_, |
| 3785 token_index_)); | 3808 TokenIndex())); |
| 3786 toplevel_class.set_library(library_); | 3809 toplevel_class.set_library(library_); |
| 3787 | 3810 |
| 3788 if (is_library_source()) { | 3811 if (is_library_source()) { |
| 3789 ParseLibraryDefinition(); | 3812 ParseLibraryDefinition(); |
| 3790 } | 3813 } |
| 3791 | 3814 |
| 3792 while (true) { | 3815 while (true) { |
| 3793 set_current_class(Class::Handle()); // No current class. | 3816 set_current_class(Class::Handle()); // No current class. |
| 3794 if (CurrentToken() == Token::kCLASS) { | 3817 if (CurrentToken() == Token::kCLASS) { |
| 3795 ParseClassDefinition(pending_classes); | 3818 ParseClassDefinition(pending_classes); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3828 | 3851 |
| 3829 library_.AddAnonymousClass(toplevel_class); | 3852 library_.AddAnonymousClass(toplevel_class); |
| 3830 pending_classes.Add(toplevel_class, Heap::kOld); | 3853 pending_classes.Add(toplevel_class, Heap::kOld); |
| 3831 } | 3854 } |
| 3832 } | 3855 } |
| 3833 | 3856 |
| 3834 | 3857 |
| 3835 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 3858 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
| 3836 Block* block = new Block(current_block_, | 3859 Block* block = new Block(current_block_, |
| 3837 outer_scope, | 3860 outer_scope, |
| 3838 new SequenceNode(token_index_, outer_scope)); | 3861 new SequenceNode(TokenIndex(), outer_scope)); |
| 3839 current_block_ = block; | 3862 current_block_ = block; |
| 3840 } | 3863 } |
| 3841 | 3864 |
| 3842 | 3865 |
| 3843 void Parser::OpenBlock() { | 3866 void Parser::OpenBlock() { |
| 3844 ASSERT(current_block_ != NULL); | 3867 ASSERT(current_block_ != NULL); |
| 3845 LocalScope* outer_scope = current_block_->scope; | 3868 LocalScope* outer_scope = current_block_->scope; |
| 3846 ChainNewBlock(new LocalScope(outer_scope, | 3869 ChainNewBlock(new LocalScope(outer_scope, |
| 3847 outer_scope->function_level(), | 3870 outer_scope->function_level(), |
| 3848 outer_scope->loop_level())); | 3871 outer_scope->loop_level())); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3882 ChainNewBlock(outer_scope); | 3905 ChainNewBlock(outer_scope); |
| 3883 } | 3906 } |
| 3884 | 3907 |
| 3885 | 3908 |
| 3886 SequenceNode* Parser::CloseBlock() { | 3909 SequenceNode* Parser::CloseBlock() { |
| 3887 SequenceNode* statements = current_block_->statements; | 3910 SequenceNode* statements = current_block_->statements; |
| 3888 if (current_block_->scope != NULL) { | 3911 if (current_block_->scope != NULL) { |
| 3889 // Record the begin and end token index of the scope. | 3912 // Record the begin and end token index of the scope. |
| 3890 ASSERT(statements != NULL); | 3913 ASSERT(statements != NULL); |
| 3891 current_block_->scope->set_begin_token_index(statements->token_index()); | 3914 current_block_->scope->set_begin_token_index(statements->token_index()); |
| 3892 current_block_->scope->set_end_token_index(token_index_); | 3915 current_block_->scope->set_end_token_index(TokenIndex()); |
| 3893 } | 3916 } |
| 3894 current_block_ = current_block_->parent; | 3917 current_block_ = current_block_->parent; |
| 3895 return statements; | 3918 return statements; |
| 3896 } | 3919 } |
| 3897 | 3920 |
| 3898 | 3921 |
| 3899 // Set up default values for all optional parameters to the function. | 3922 // Set up default values for all optional parameters to the function. |
| 3900 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 3923 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 3901 Array& default_values) { | 3924 Array& default_values) { |
| 3902 if (params->num_optional_parameters > 0) { | 3925 if (params->num_optional_parameters > 0) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3963 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 3986 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 3964 const Function& func) { | 3987 const Function& func) { |
| 3965 func.set_is_native(true); | 3988 func.set_is_native(true); |
| 3966 TRACE_PARSER("ParseNativeFunctionBlock"); | 3989 TRACE_PARSER("ParseNativeFunctionBlock"); |
| 3967 const Class& cls = Class::Handle(func.owner()); | 3990 const Class& cls = Class::Handle(func.owner()); |
| 3968 const int num_parameters = params->parameters->length(); | 3991 const int num_parameters = params->parameters->length(); |
| 3969 const bool is_instance_closure = func.IsImplicitInstanceClosureFunction(); | 3992 const bool is_instance_closure = func.IsImplicitInstanceClosureFunction(); |
| 3970 int num_params_for_resolution = num_parameters; | 3993 int num_params_for_resolution = num_parameters; |
| 3971 | 3994 |
| 3972 // Parse the function name out. | 3995 // Parse the function name out. |
| 3973 const intptr_t native_pos = token_index_; | 3996 const intptr_t native_pos = TokenIndex(); |
| 3974 const String& native_name = ParseNativeDeclaration(); | 3997 const String& native_name = ParseNativeDeclaration(); |
| 3975 | 3998 |
| 3976 if (is_instance_closure) { | 3999 if (is_instance_closure) { |
| 3977 num_params_for_resolution += 1; // account for 'this' when resolving. | 4000 num_params_for_resolution += 1; // account for 'this' when resolving. |
| 3978 } | 4001 } |
| 3979 // Now resolve the native function to the corresponding native entrypoint. | 4002 // Now resolve the native function to the corresponding native entrypoint. |
| 3980 NativeFunction native_function = NativeEntry::ResolveNative( | 4003 NativeFunction native_function = NativeEntry::ResolveNative( |
| 3981 cls, native_name, num_params_for_resolution); | 4004 cls, native_name, num_params_for_resolution); |
| 3982 if (native_function == NULL) { | 4005 if (native_function == NULL) { |
| 3983 ErrorMsg(native_pos, "native function '%s' cannot be found", | 4006 ErrorMsg(native_pos, "native function '%s' cannot be found", |
| 3984 native_name.ToCString()); | 4007 native_name.ToCString()); |
| 3985 } | 4008 } |
| 3986 | 4009 |
| 3987 const bool has_opt_params = (params->num_optional_parameters > 0); | 4010 const bool has_opt_params = (params->num_optional_parameters > 0); |
| 3988 | 4011 |
| 3989 // Now add the NativeBodyNode and return statement. | 4012 // Now add the NativeBodyNode and return statement. |
| 3990 current_block_->statements->Add( | 4013 current_block_->statements->Add( |
| 3991 new ReturnNode(token_index_, new NativeBodyNode(token_index_, | 4014 new ReturnNode(TokenIndex(), new NativeBodyNode(TokenIndex(), |
| 3992 native_name, | 4015 native_name, |
| 3993 native_function, | 4016 native_function, |
| 3994 num_parameters, | 4017 num_parameters, |
| 3995 has_opt_params, | 4018 has_opt_params, |
| 3996 is_instance_closure))); | 4019 is_instance_closure))); |
| 3997 } | 4020 } |
| 3998 | 4021 |
| 3999 | 4022 |
| 4000 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, | 4023 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, |
| 4001 bool test_only) { | 4024 bool test_only) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 4025 // A nested function may access 'this', referring to the receiver of the | 4048 // A nested function may access 'this', referring to the receiver of the |
| 4026 // outermost enclosing function. | 4049 // outermost enclosing function. |
| 4027 // We should not be loading the receiver from a static scope. | 4050 // We should not be loading the receiver from a static scope. |
| 4028 ASSERT(!current_function().is_static() || | 4051 ASSERT(!current_function().is_static() || |
| 4029 current_function().IsInFactoryScope()); | 4052 current_function().IsInFactoryScope()); |
| 4030 const bool kTestOnly = false; | 4053 const bool kTestOnly = false; |
| 4031 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 4054 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 4032 if (receiver == NULL) { | 4055 if (receiver == NULL) { |
| 4033 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); | 4056 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); |
| 4034 } | 4057 } |
| 4035 return new LoadLocalNode(token_index_, *receiver); | 4058 return new LoadLocalNode(TokenIndex(), *receiver); |
| 4036 } | 4059 } |
| 4037 | 4060 |
| 4038 | 4061 |
| 4039 AstNode* Parser::CallGetter(intptr_t token_index, | 4062 AstNode* Parser::CallGetter(intptr_t token_index, |
| 4040 AstNode* object, | 4063 AstNode* object, |
| 4041 const String& name) { | 4064 const String& name) { |
| 4042 return new InstanceGetterNode(token_index_, object, name); | 4065 return new InstanceGetterNode(TokenIndex(), object, name); |
| 4043 } | 4066 } |
| 4044 | 4067 |
| 4045 | 4068 |
| 4046 // Returns ast nodes of the variable initialization. | 4069 // Returns ast nodes of the variable initialization. |
| 4047 AstNode* Parser::ParseVariableDeclaration( | 4070 AstNode* Parser::ParseVariableDeclaration( |
| 4048 const AbstractType& type, bool is_final) { | 4071 const AbstractType& type, bool is_final) { |
| 4049 TRACE_PARSER("ParseVariableDeclaration"); | 4072 TRACE_PARSER("ParseVariableDeclaration"); |
| 4050 ASSERT(IsIdentifier()); | 4073 ASSERT(IsIdentifier()); |
| 4051 const intptr_t ident_pos = token_index_; | 4074 const intptr_t ident_pos = TokenIndex(); |
| 4052 LocalVariable* variable = | 4075 LocalVariable* variable = |
| 4053 new LocalVariable(ident_pos, *CurrentLiteral(), type); | 4076 new LocalVariable(ident_pos, *CurrentLiteral(), type); |
| 4054 ASSERT(current_block_ != NULL); | 4077 ASSERT(current_block_ != NULL); |
| 4055 ASSERT(current_block_->scope != NULL); | 4078 ASSERT(current_block_->scope != NULL); |
| 4056 ConsumeToken(); // Variable identifier. | 4079 ConsumeToken(); // Variable identifier. |
| 4057 AstNode* initialization = NULL; | 4080 AstNode* initialization = NULL; |
| 4058 if (CurrentToken() == Token::kASSIGN) { | 4081 if (CurrentToken() == Token::kASSIGN) { |
| 4059 // Variable initialization. | 4082 // Variable initialization. |
| 4060 const intptr_t assign_pos = token_index_; | 4083 const intptr_t assign_pos = TokenIndex(); |
| 4061 ConsumeToken(); | 4084 ConsumeToken(); |
| 4062 AstNode* expr = ParseExpr(kAllowConst); | 4085 AstNode* expr = ParseExpr(kAllowConst); |
| 4063 initialization = new StoreLocalNode(assign_pos, *variable, expr); | 4086 initialization = new StoreLocalNode(assign_pos, *variable, expr); |
| 4064 } else if (is_final) { | 4087 } else if (is_final) { |
| 4065 ErrorMsg(ident_pos, "missing initialization of 'final' variable"); | 4088 ErrorMsg(ident_pos, "missing initialization of 'final' variable"); |
| 4066 } else { | 4089 } else { |
| 4067 // Initialize variable with null. | 4090 // Initialize variable with null. |
| 4068 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); | 4091 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); |
| 4069 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); | 4092 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); |
| 4070 } | 4093 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4158 const String* function_name = NULL; | 4181 const String* function_name = NULL; |
| 4159 | 4182 |
| 4160 result_type = Type::DynamicType(); | 4183 result_type = Type::DynamicType(); |
| 4161 if (CurrentToken() == Token::kVOID) { | 4184 if (CurrentToken() == Token::kVOID) { |
| 4162 ConsumeToken(); | 4185 ConsumeToken(); |
| 4163 result_type = Type::VoidType(); | 4186 result_type = Type::VoidType(); |
| 4164 } else if ((CurrentToken() == Token::kIDENT) && | 4187 } else if ((CurrentToken() == Token::kIDENT) && |
| 4165 (LookaheadToken(1) != Token::kLPAREN)) { | 4188 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4166 result_type = ParseType(ClassFinalizer::kFinalize); | 4189 result_type = ParseType(ClassFinalizer::kFinalize); |
| 4167 } | 4190 } |
| 4168 const intptr_t ident_pos = token_index_; | 4191 const intptr_t ident_pos = TokenIndex(); |
| 4169 if (IsIdentifier()) { | 4192 if (IsIdentifier()) { |
| 4170 variable_name = CurrentLiteral(); | 4193 variable_name = CurrentLiteral(); |
| 4171 function_name = variable_name; | 4194 function_name = variable_name; |
| 4172 ConsumeToken(); | 4195 ConsumeToken(); |
| 4173 } else { | 4196 } else { |
| 4174 if (!is_literal) { | 4197 if (!is_literal) { |
| 4175 ErrorMsg("function name expected"); | 4198 ErrorMsg("function name expected"); |
| 4176 } | 4199 } |
| 4177 const String& anonymous_function_name = | 4200 const String& anonymous_function_name = |
| 4178 String::ZoneHandle(String::NewSymbol("function")); | 4201 String::ZoneHandle(String::NewSymbol("function")); |
| 4179 function_name = &anonymous_function_name; | 4202 function_name = &anonymous_function_name; |
| 4180 } | 4203 } |
| 4181 ASSERT(ident_pos >= 0); | 4204 ASSERT(ident_pos >= 0); |
| 4182 | 4205 |
| 4183 if (CurrentToken() != Token::kLPAREN) { | 4206 if (CurrentToken() != Token::kLPAREN) { |
| 4184 ErrorMsg("'(' expected"); | 4207 ErrorMsg("'(' expected"); |
| 4185 } | 4208 } |
| 4186 intptr_t function_pos = token_index_; | 4209 intptr_t function_pos = TokenIndex(); |
| 4187 | 4210 |
| 4188 // Check whether we have parsed this closure function before, in a previous | 4211 // Check whether we have parsed this closure function before, in a previous |
| 4189 // compilation. If so, reuse the function object, else create a new one | 4212 // compilation. If so, reuse the function object, else create a new one |
| 4190 // and register it in the current class. | 4213 // and register it in the current class. |
| 4191 // Note that we cannot share the same closure function between the closurized | 4214 // Note that we cannot share the same closure function between the closurized |
| 4192 // and non-closurized versions of the same parent function. | 4215 // and non-closurized versions of the same parent function. |
| 4193 Function& function = Function::ZoneHandle(); | 4216 Function& function = Function::ZoneHandle(); |
| 4194 bool is_new_closure = false; | 4217 bool is_new_closure = false; |
| 4195 // TODO(hausner): There could be two different closures at the given | 4218 // TODO(hausner): There could be two different closures at the given |
| 4196 // function_pos, one enclosed in a closurized function and one enclosed in the | 4219 // function_pos, one enclosed in a closurized function and one enclosed in the |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4236 if (!current_block_->scope->AddVariable(function_variable)) { | 4259 if (!current_block_->scope->AddVariable(function_variable)) { |
| 4237 ErrorMsg(ident_pos, "identifier '%s' already defined", | 4260 ErrorMsg(ident_pos, "identifier '%s' already defined", |
| 4238 function_variable->name().ToCString()); | 4261 function_variable->name().ToCString()); |
| 4239 } | 4262 } |
| 4240 } | 4263 } |
| 4241 | 4264 |
| 4242 // Parse the local function. | 4265 // Parse the local function. |
| 4243 Array& default_parameter_values = Array::Handle(); | 4266 Array& default_parameter_values = Array::Handle(); |
| 4244 SequenceNode* statements = Parser::ParseFunc(function, | 4267 SequenceNode* statements = Parser::ParseFunc(function, |
| 4245 default_parameter_values); | 4268 default_parameter_values); |
| 4246 ASSERT(is_new_closure || (function.end_token_index() == token_index_)); | 4269 ASSERT(is_new_closure || (function.end_token_index() == TokenIndex())); |
| 4247 function.set_end_token_index(token_index_); | 4270 function.set_end_token_index(TokenIndex()); |
| 4248 | 4271 |
| 4249 // Now that the local function has formal parameters, lookup the signature | 4272 // Now that the local function has formal parameters, lookup the signature |
| 4250 // class in the current library (but not in its imports) and only create a new | 4273 // class in the current library (but not in its imports) and only create a new |
| 4251 // canonical signature class if it does not exist yet. | 4274 // canonical signature class if it does not exist yet. |
| 4252 const String& signature = String::Handle(function.Signature()); | 4275 const String& signature = String::Handle(function.Signature()); |
| 4253 Class& signature_class = Class::ZoneHandle( | 4276 Class& signature_class = Class::ZoneHandle( |
| 4254 library_.LookupLocalClass(signature)); | 4277 library_.LookupLocalClass(signature)); |
| 4255 | 4278 |
| 4256 if (signature_class.IsNull()) { | 4279 if (signature_class.IsNull()) { |
| 4257 // If we don't have a signature class yet, this must be a closure we | 4280 // If we don't have a signature class yet, this must be a closure we |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4416 // Token position remains unchanged. | 4439 // Token position remains unchanged. |
| 4417 bool Parser::IsVariableDeclaration() { | 4440 bool Parser::IsVariableDeclaration() { |
| 4418 if ((CurrentToken() == Token::kVAR) || | 4441 if ((CurrentToken() == Token::kVAR) || |
| 4419 (CurrentToken() == Token::kFINAL)) { | 4442 (CurrentToken() == Token::kFINAL)) { |
| 4420 return true; | 4443 return true; |
| 4421 } | 4444 } |
| 4422 if (CurrentToken() != Token::kIDENT) { | 4445 if (CurrentToken() != Token::kIDENT) { |
| 4423 // Not a legal type identifier. | 4446 // Not a legal type identifier. |
| 4424 return false; | 4447 return false; |
| 4425 } | 4448 } |
| 4426 const intptr_t saved_pos = token_index_; | 4449 const intptr_t saved_pos = TokenIndex(); |
| 4427 bool is_var_decl = false; | 4450 bool is_var_decl = false; |
| 4428 if (TryParseOptionalType()) { | 4451 if (TryParseOptionalType()) { |
| 4429 if (IsIdentifier()) { | 4452 if (IsIdentifier()) { |
| 4430 ConsumeToken(); | 4453 ConsumeToken(); |
| 4431 if ((CurrentToken() == Token::kSEMICOLON) || | 4454 if ((CurrentToken() == Token::kSEMICOLON) || |
| 4432 (CurrentToken() == Token::kCOMMA) || | 4455 (CurrentToken() == Token::kCOMMA) || |
| 4433 (CurrentToken() == Token::kASSIGN)) { | 4456 (CurrentToken() == Token::kASSIGN)) { |
| 4434 is_var_decl = true; | 4457 is_var_decl = true; |
| 4435 } | 4458 } |
| 4436 } | 4459 } |
| 4437 } | 4460 } |
| 4438 SetPosition(saved_pos); | 4461 SetPosition(saved_pos); |
| 4439 return is_var_decl; | 4462 return is_var_decl; |
| 4440 } | 4463 } |
| 4441 | 4464 |
| 4442 | 4465 |
| 4443 // Look ahead to detect whether the next tokens should be parsed as | 4466 // Look ahead to detect whether the next tokens should be parsed as |
| 4444 // a function declaration. Token position remains unchanged. | 4467 // a function declaration. Token position remains unchanged. |
| 4445 bool Parser::IsFunctionDeclaration() { | 4468 bool Parser::IsFunctionDeclaration() { |
| 4446 const intptr_t saved_pos = token_index_; | 4469 const intptr_t saved_pos = TokenIndex(); |
| 4447 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4470 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4448 // Possibly a function without explicit return type. | 4471 // Possibly a function without explicit return type. |
| 4449 ConsumeToken(); // Consume function identifier. | 4472 ConsumeToken(); // Consume function identifier. |
| 4450 } else if (TryParseReturnType()) { | 4473 } else if (TryParseReturnType()) { |
| 4451 if (!IsIdentifier()) { | 4474 if (!IsIdentifier()) { |
| 4452 SetPosition(saved_pos); | 4475 SetPosition(saved_pos); |
| 4453 return false; | 4476 return false; |
| 4454 } | 4477 } |
| 4455 ConsumeToken(); // Consume function identifier. | 4478 ConsumeToken(); // Consume function identifier. |
| 4456 } else { | 4479 } else { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 4469 } | 4492 } |
| 4470 SetPosition(saved_pos); | 4493 SetPosition(saved_pos); |
| 4471 return false; | 4494 return false; |
| 4472 } | 4495 } |
| 4473 | 4496 |
| 4474 | 4497 |
| 4475 bool Parser::IsTopLevelAccessor() { | 4498 bool Parser::IsTopLevelAccessor() { |
| 4476 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4499 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4477 return true; | 4500 return true; |
| 4478 } | 4501 } |
| 4479 const intptr_t saved_pos = token_index_; | 4502 const intptr_t saved_pos = TokenIndex(); |
| 4480 if (TryParseReturnType()) { | 4503 if (TryParseReturnType()) { |
| 4481 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4504 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4482 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 4505 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 4483 SetPosition(saved_pos); | 4506 SetPosition(saved_pos); |
| 4484 return true; | 4507 return true; |
| 4485 } | 4508 } |
| 4486 } | 4509 } |
| 4487 } | 4510 } |
| 4488 SetPosition(saved_pos); | 4511 SetPosition(saved_pos); |
| 4489 return false; | 4512 return false; |
| 4490 } | 4513 } |
| 4491 | 4514 |
| 4492 | 4515 |
| 4493 bool Parser::IsFunctionLiteral() { | 4516 bool Parser::IsFunctionLiteral() { |
| 4494 if (!allow_function_literals_) { | 4517 if (!allow_function_literals_) { |
| 4495 return false; | 4518 return false; |
| 4496 } | 4519 } |
| 4497 const intptr_t saved_pos = token_index_; | 4520 const intptr_t saved_pos = TokenIndex(); |
| 4498 bool is_function_literal = false; | 4521 bool is_function_literal = false; |
| 4499 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4522 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4500 ConsumeToken(); // Consume function identifier. | 4523 ConsumeToken(); // Consume function identifier. |
| 4501 } else if (TryParseReturnType()) { | 4524 } else if (TryParseReturnType()) { |
| 4502 if (!IsIdentifier()) { | 4525 if (!IsIdentifier()) { |
| 4503 SetPosition(saved_pos); | 4526 SetPosition(saved_pos); |
| 4504 return false; | 4527 return false; |
| 4505 } | 4528 } |
| 4506 ConsumeToken(); // Comsume function identifier. | 4529 ConsumeToken(); // Comsume function identifier. |
| 4507 } | 4530 } |
| 4508 if (CurrentToken() == Token::kLPAREN) { | 4531 if (CurrentToken() == Token::kLPAREN) { |
| 4509 SkipToMatchingParenthesis(); | 4532 SkipToMatchingParenthesis(); |
| 4510 if ((CurrentToken() == Token::kLBRACE) || | 4533 if ((CurrentToken() == Token::kLBRACE) || |
| 4511 (CurrentToken() == Token::kARROW)) { | 4534 (CurrentToken() == Token::kARROW)) { |
| 4512 is_function_literal = true; | 4535 is_function_literal = true; |
| 4513 } | 4536 } |
| 4514 } | 4537 } |
| 4515 SetPosition(saved_pos); | 4538 SetPosition(saved_pos); |
| 4516 return is_function_literal; | 4539 return is_function_literal; |
| 4517 } | 4540 } |
| 4518 | 4541 |
| 4519 | 4542 |
| 4520 // Current token position is the token after the opening ( of the for | 4543 // Current token position is the token after the opening ( of the for |
| 4521 // statement. Returns true if we recognize a for ( .. in expr) | 4544 // statement. Returns true if we recognize a for ( .. in expr) |
| 4522 // statement. | 4545 // statement. |
| 4523 bool Parser::IsForInStatement() { | 4546 bool Parser::IsForInStatement() { |
| 4524 const intptr_t saved_pos = token_index_; | 4547 const intptr_t saved_pos = TokenIndex(); |
| 4525 bool result = false; | 4548 bool result = false; |
| 4526 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { | 4549 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { |
| 4527 ConsumeToken(); | 4550 ConsumeToken(); |
| 4528 } | 4551 } |
| 4529 if (IsIdentifier()) { | 4552 if (IsIdentifier()) { |
| 4530 if (LookaheadToken(1) == Token::kIN) { | 4553 if (LookaheadToken(1) == Token::kIN) { |
| 4531 result = true; | 4554 result = true; |
| 4532 } else if (TryParseOptionalType()) { | 4555 } else if (TryParseOptionalType()) { |
| 4533 if (IsIdentifier()) { | 4556 if (IsIdentifier()) { |
| 4534 ConsumeToken(); | 4557 ConsumeToken(); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 4560 } | 4583 } |
| 4561 return false; | 4584 return false; |
| 4562 } | 4585 } |
| 4563 | 4586 |
| 4564 | 4587 |
| 4565 void Parser::ParseStatementSequence() { | 4588 void Parser::ParseStatementSequence() { |
| 4566 TRACE_PARSER("ParseStatementSequence"); | 4589 TRACE_PARSER("ParseStatementSequence"); |
| 4567 const bool dead_code_allowed = true; | 4590 const bool dead_code_allowed = true; |
| 4568 bool abrupt_completing_seen = false; | 4591 bool abrupt_completing_seen = false; |
| 4569 while (CurrentToken() != Token::kRBRACE) { | 4592 while (CurrentToken() != Token::kRBRACE) { |
| 4570 const intptr_t statement_pos = token_index_; | 4593 const intptr_t statement_pos = TokenIndex(); |
| 4571 AstNode* statement = ParseStatement(); | 4594 AstNode* statement = ParseStatement(); |
| 4572 // Do not add statements with no effect (e.g., LoadLocalNode). | 4595 // Do not add statements with no effect (e.g., LoadLocalNode). |
| 4573 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 4596 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
| 4574 // Skip load local. | 4597 // Skip load local. |
| 4575 statement = statement->AsLoadLocalNode()->pseudo(); | 4598 statement = statement->AsLoadLocalNode()->pseudo(); |
| 4576 } | 4599 } |
| 4577 if (statement != NULL) { | 4600 if (statement != NULL) { |
| 4578 if (!dead_code_allowed && abrupt_completing_seen) { | 4601 if (!dead_code_allowed && abrupt_completing_seen) { |
| 4579 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); | 4602 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); |
| 4580 } | 4603 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 4610 } | 4633 } |
| 4611 } | 4634 } |
| 4612 SequenceNode* sequence = CloseBlock(); | 4635 SequenceNode* sequence = CloseBlock(); |
| 4613 return sequence; | 4636 return sequence; |
| 4614 } | 4637 } |
| 4615 | 4638 |
| 4616 | 4639 |
| 4617 AstNode* Parser::ParseIfStatement(String* label_name) { | 4640 AstNode* Parser::ParseIfStatement(String* label_name) { |
| 4618 TRACE_PARSER("ParseIfStatement"); | 4641 TRACE_PARSER("ParseIfStatement"); |
| 4619 ASSERT(CurrentToken() == Token::kIF); | 4642 ASSERT(CurrentToken() == Token::kIF); |
| 4620 const intptr_t if_pos = token_index_; | 4643 const intptr_t if_pos = TokenIndex(); |
| 4621 SourceLabel* label = NULL; | 4644 SourceLabel* label = NULL; |
| 4622 if (label_name != NULL) { | 4645 if (label_name != NULL) { |
| 4623 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 4646 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
| 4624 OpenBlock(); | 4647 OpenBlock(); |
| 4625 current_block_->scope->AddLabel(label); | 4648 current_block_->scope->AddLabel(label); |
| 4626 } | 4649 } |
| 4627 ConsumeToken(); | 4650 ConsumeToken(); |
| 4628 ExpectToken(Token::kLPAREN); | 4651 ExpectToken(Token::kLPAREN); |
| 4629 AstNode* cond_expr = ParseExpr(kAllowConst); | 4652 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4630 ExpectToken(Token::kRPAREN); | 4653 ExpectToken(Token::kRPAREN); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 4643 if_node = sequence; | 4666 if_node = sequence; |
| 4644 } | 4667 } |
| 4645 return if_node; | 4668 return if_node; |
| 4646 } | 4669 } |
| 4647 | 4670 |
| 4648 | 4671 |
| 4649 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 4672 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 4650 SourceLabel* case_label) { | 4673 SourceLabel* case_label) { |
| 4651 TRACE_PARSER("ParseCaseStatement"); | 4674 TRACE_PARSER("ParseCaseStatement"); |
| 4652 bool default_seen = false; | 4675 bool default_seen = false; |
| 4653 const intptr_t case_pos = token_index_; | 4676 const intptr_t case_pos = TokenIndex(); |
| 4654 // The case expressions node sequence does not own the enclosing scope. | 4677 // The case expressions node sequence does not own the enclosing scope. |
| 4655 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); | 4678 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); |
| 4656 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 4679 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 4657 if (CurrentToken() == Token::kCASE) { | 4680 if (CurrentToken() == Token::kCASE) { |
| 4658 if (default_seen) { | 4681 if (default_seen) { |
| 4659 ErrorMsg("default clause must be last case"); | 4682 ErrorMsg("default clause must be last case"); |
| 4660 } | 4683 } |
| 4661 ConsumeToken(); // Keyword case. | 4684 ConsumeToken(); // Keyword case. |
| 4662 const intptr_t expr_pos = token_index_; | 4685 const intptr_t expr_pos = TokenIndex(); |
| 4663 AstNode* expr = ParseExpr(kAllowConst); | 4686 AstNode* expr = ParseExpr(kAllowConst); |
| 4664 AstNode* switch_expr_load = new LoadLocalNode(case_pos, | 4687 AstNode* switch_expr_load = new LoadLocalNode(case_pos, |
| 4665 *switch_expr_value); | 4688 *switch_expr_value); |
| 4666 AstNode* case_comparison = new ComparisonNode(expr_pos, | 4689 AstNode* case_comparison = new ComparisonNode(expr_pos, |
| 4667 Token::kEQ, | 4690 Token::kEQ, |
| 4668 expr, | 4691 expr, |
| 4669 switch_expr_load); | 4692 switch_expr_load); |
| 4670 case_expressions->Add(case_comparison); | 4693 case_expressions->Add(case_comparison); |
| 4671 } else { | 4694 } else { |
| 4672 if (default_seen) { | 4695 if (default_seen) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 4692 next_token = CurrentToken(); | 4715 next_token = CurrentToken(); |
| 4693 } | 4716 } |
| 4694 if (next_token == Token::kRBRACE) { | 4717 if (next_token == Token::kRBRACE) { |
| 4695 // End of switch statement. | 4718 // End of switch statement. |
| 4696 break; | 4719 break; |
| 4697 } | 4720 } |
| 4698 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 4721 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
| 4699 // End of this case clause. If there is a possible fall-through to | 4722 // End of this case clause. If there is a possible fall-through to |
| 4700 // the next case clause, throw an implicit FallThroughError. | 4723 // the next case clause, throw an implicit FallThroughError. |
| 4701 if (!abrupt_completing_seen) { | 4724 if (!abrupt_completing_seen) { |
| 4702 ArgumentListNode* arguments = new ArgumentListNode(token_index_); | 4725 ArgumentListNode* arguments = new ArgumentListNode(TokenIndex()); |
| 4703 arguments->Add(new LiteralNode( | 4726 arguments->Add(new LiteralNode( |
| 4704 token_index_, Integer::ZoneHandle(Integer::New(token_index_)))); | 4727 TokenIndex(), Integer::ZoneHandle(Integer::New(TokenIndex())))); |
| 4705 current_block_->statements->Add( | 4728 current_block_->statements->Add( |
| 4706 MakeStaticCall(kFallThroughErrorName, kThrowNewName, arguments)); | 4729 MakeStaticCall(kFallThroughErrorName, kThrowNewName, arguments)); |
| 4707 } | 4730 } |
| 4708 break; | 4731 break; |
| 4709 } | 4732 } |
| 4710 // The next statement still belongs to this case. | 4733 // The next statement still belongs to this case. |
| 4711 AstNode* statement = ParseStatement(); | 4734 AstNode* statement = ParseStatement(); |
| 4712 if (statement != NULL) { | 4735 if (statement != NULL) { |
| 4713 current_block_->statements->Add(statement); | 4736 current_block_->statements->Add(statement); |
| 4714 abrupt_completing_seen |= IsAbruptCompleting(statement); | 4737 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 4715 } | 4738 } |
| 4716 } | 4739 } |
| 4717 SequenceNode* statements = CloseBlock(); | 4740 SequenceNode* statements = CloseBlock(); |
| 4718 return new CaseNode(case_pos, case_label, | 4741 return new CaseNode(case_pos, case_label, |
| 4719 case_expressions, default_seen, switch_expr_value, statements); | 4742 case_expressions, default_seen, switch_expr_value, statements); |
| 4720 } | 4743 } |
| 4721 | 4744 |
| 4722 | 4745 |
| 4723 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 4746 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 4724 TRACE_PARSER("ParseSwitchStatement"); | 4747 TRACE_PARSER("ParseSwitchStatement"); |
| 4725 ASSERT(CurrentToken() == Token::kSWITCH); | 4748 ASSERT(CurrentToken() == Token::kSWITCH); |
| 4726 const intptr_t switch_pos = token_index_; | 4749 const intptr_t switch_pos = TokenIndex(); |
| 4727 SourceLabel* label = | 4750 SourceLabel* label = |
| 4728 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 4751 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 4729 ConsumeToken(); | 4752 ConsumeToken(); |
| 4730 const bool parens_are_mandatory = false; | 4753 const bool parens_are_mandatory = false; |
| 4731 bool paren_found = false; | 4754 bool paren_found = false; |
| 4732 if (CurrentToken() == Token::kLPAREN) { | 4755 if (CurrentToken() == Token::kLPAREN) { |
| 4733 paren_found = true; | 4756 paren_found = true; |
| 4734 ConsumeToken(); | 4757 ConsumeToken(); |
| 4735 } else if (parens_are_mandatory) { | 4758 } else if (parens_are_mandatory) { |
| 4736 ErrorMsg("'(' expected"); | 4759 ErrorMsg("'(' expected"); |
| 4737 } | 4760 } |
| 4738 const intptr_t expr_pos = token_index_; | 4761 const intptr_t expr_pos = TokenIndex(); |
| 4739 AstNode* switch_expr = ParseExpr(kAllowConst); | 4762 AstNode* switch_expr = ParseExpr(kAllowConst); |
| 4740 if (paren_found) { | 4763 if (paren_found) { |
| 4741 ExpectToken(Token::kRPAREN); | 4764 ExpectToken(Token::kRPAREN); |
| 4742 } | 4765 } |
| 4743 ExpectToken(Token::kLBRACE); | 4766 ExpectToken(Token::kLBRACE); |
| 4744 OpenBlock(); | 4767 OpenBlock(); |
| 4745 current_block_->scope->AddLabel(label); | 4768 current_block_->scope->AddLabel(label); |
| 4746 | 4769 |
| 4747 // Store switch expression in temporary local variable. | 4770 // Store switch expression in temporary local variable. |
| 4748 LocalVariable* temp_variable = | 4771 LocalVariable* temp_variable = |
| 4749 new LocalVariable(expr_pos, | 4772 new LocalVariable(expr_pos, |
| 4750 String::ZoneHandle(String::NewSymbol(":switch_expr")), | 4773 String::ZoneHandle(String::NewSymbol(":switch_expr")), |
| 4751 Type::ZoneHandle(Type::DynamicType())); | 4774 Type::ZoneHandle(Type::DynamicType())); |
| 4752 current_block_->scope->AddVariable(temp_variable); | 4775 current_block_->scope->AddVariable(temp_variable); |
| 4753 AstNode* save_switch_expr = | 4776 AstNode* save_switch_expr = |
| 4754 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 4777 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
| 4755 current_block_->statements->Add(save_switch_expr); | 4778 current_block_->statements->Add(save_switch_expr); |
| 4756 | 4779 |
| 4757 // Parse case clauses | 4780 // Parse case clauses |
| 4758 bool default_seen = false; | 4781 bool default_seen = false; |
| 4759 while (true) { | 4782 while (true) { |
| 4760 // Check for statement label | 4783 // Check for statement label |
| 4761 SourceLabel* case_label = NULL; | 4784 SourceLabel* case_label = NULL; |
| 4762 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 4785 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 4763 // Case statements start with a label. | 4786 // Case statements start with a label. |
| 4764 String* label_name = CurrentLiteral(); | 4787 String* label_name = CurrentLiteral(); |
| 4765 const intptr_t label_pos = token_index_; | 4788 const intptr_t label_pos = TokenIndex(); |
| 4766 ConsumeToken(); // Consume label identifier. | 4789 ConsumeToken(); // Consume label identifier. |
| 4767 ConsumeToken(); // Consume colon. | 4790 ConsumeToken(); // Consume colon. |
| 4768 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 4791 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 4769 if (case_label == NULL) { | 4792 if (case_label == NULL) { |
| 4770 // Label does not exist yet. Add it to scope of switch statement. | 4793 // Label does not exist yet. Add it to scope of switch statement. |
| 4771 case_label = | 4794 case_label = |
| 4772 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); | 4795 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
| 4773 current_block_->scope->AddLabel(case_label); | 4796 current_block_->scope->AddLabel(case_label); |
| 4774 } else if (case_label->kind() == SourceLabel::kForward) { | 4797 } else if (case_label->kind() == SourceLabel::kForward) { |
| 4775 // We have seen a 'continue' with this label name. Resolve | 4798 // We have seen a 'continue' with this label name. Resolve |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4807 } | 4830 } |
| 4808 | 4831 |
| 4809 SequenceNode* switch_body = CloseBlock(); | 4832 SequenceNode* switch_body = CloseBlock(); |
| 4810 ExpectToken(Token::kRBRACE); | 4833 ExpectToken(Token::kRBRACE); |
| 4811 return new SwitchNode(switch_pos, label, switch_body); | 4834 return new SwitchNode(switch_pos, label, switch_body); |
| 4812 } | 4835 } |
| 4813 | 4836 |
| 4814 | 4837 |
| 4815 AstNode* Parser::ParseWhileStatement(String* label_name) { | 4838 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 4816 TRACE_PARSER("ParseWhileStatement"); | 4839 TRACE_PARSER("ParseWhileStatement"); |
| 4817 const intptr_t while_pos = token_index_; | 4840 const intptr_t while_pos = TokenIndex(); |
| 4818 SourceLabel* label = | 4841 SourceLabel* label = |
| 4819 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 4842 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 4820 ConsumeToken(); | 4843 ConsumeToken(); |
| 4821 ExpectToken(Token::kLPAREN); | 4844 ExpectToken(Token::kLPAREN); |
| 4822 AstNode* cond_expr = ParseExpr(kAllowConst); | 4845 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4823 ExpectToken(Token::kRPAREN); | 4846 ExpectToken(Token::kRPAREN); |
| 4824 const bool parsing_loop_body = true; | 4847 const bool parsing_loop_body = true; |
| 4825 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 4848 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 4826 return new WhileNode(while_pos, label, cond_expr, while_body); | 4849 return new WhileNode(while_pos, label, cond_expr, while_body); |
| 4827 } | 4850 } |
| 4828 | 4851 |
| 4829 | 4852 |
| 4830 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 4853 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 4831 TRACE_PARSER("ParseDoWhileStatement"); | 4854 TRACE_PARSER("ParseDoWhileStatement"); |
| 4832 const intptr_t do_pos = token_index_; | 4855 const intptr_t do_pos = TokenIndex(); |
| 4833 SourceLabel* label = | 4856 SourceLabel* label = |
| 4834 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 4857 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 4835 ConsumeToken(); | 4858 ConsumeToken(); |
| 4836 const bool parsing_loop_body = true; | 4859 const bool parsing_loop_body = true; |
| 4837 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 4860 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 4838 ExpectToken(Token::kWHILE); | 4861 ExpectToken(Token::kWHILE); |
| 4839 ExpectToken(Token::kLPAREN); | 4862 ExpectToken(Token::kLPAREN); |
| 4840 AstNode* cond_expr = ParseExpr(kAllowConst); | 4863 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4841 ExpectToken(Token::kRPAREN); | 4864 ExpectToken(Token::kRPAREN); |
| 4842 ExpectSemicolon(); | 4865 ExpectSemicolon(); |
| 4843 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 4866 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 4844 } | 4867 } |
| 4845 | 4868 |
| 4846 | 4869 |
| 4847 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 4870 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 4848 SourceLabel* label) { | 4871 SourceLabel* label) { |
| 4849 TRACE_PARSER("ParseForInStatement"); | 4872 TRACE_PARSER("ParseForInStatement"); |
| 4850 bool is_final = (CurrentToken() == Token::kFINAL); | 4873 bool is_final = (CurrentToken() == Token::kFINAL); |
| 4851 const String* loop_var_name = NULL; | 4874 const String* loop_var_name = NULL; |
| 4852 LocalVariable* loop_var = NULL; | 4875 LocalVariable* loop_var = NULL; |
| 4853 intptr_t loop_var_pos = 0; | 4876 intptr_t loop_var_pos = 0; |
| 4854 if (LookaheadToken(1) == Token::kIN) { | 4877 if (LookaheadToken(1) == Token::kIN) { |
| 4855 loop_var_pos = token_index_; | 4878 loop_var_pos = TokenIndex(); |
| 4856 loop_var_name = ExpectIdentifier("variable name expected"); | 4879 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4857 } else { | 4880 } else { |
| 4858 // The case without a type is handled above, so require a type here. | 4881 // The case without a type is handled above, so require a type here. |
| 4859 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 4882 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 4860 FLAG_enable_type_checks ? ClassFinalizer::kFinalize : | 4883 FLAG_enable_type_checks ? ClassFinalizer::kFinalize : |
| 4861 ClassFinalizer::kIgnore)); | 4884 ClassFinalizer::kIgnore)); |
| 4862 loop_var_pos = token_index_; | 4885 loop_var_pos = TokenIndex(); |
| 4863 loop_var_name = ExpectIdentifier("variable name expected"); | 4886 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4864 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); | 4887 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); |
| 4865 if (is_final) { | 4888 if (is_final) { |
| 4866 loop_var->set_is_final(); | 4889 loop_var->set_is_final(); |
| 4867 } | 4890 } |
| 4868 } | 4891 } |
| 4869 ExpectToken(Token::kIN); | 4892 ExpectToken(Token::kIN); |
| 4870 const intptr_t collection_pos = token_index_; | 4893 const intptr_t collection_pos = TokenIndex(); |
| 4871 AstNode* collection_expr = ParseExpr(kAllowConst); | 4894 AstNode* collection_expr = ParseExpr(kAllowConst); |
| 4872 ExpectToken(Token::kRPAREN); | 4895 ExpectToken(Token::kRPAREN); |
| 4873 | 4896 |
| 4874 OpenBlock(); // Implicit block around while loop. | 4897 OpenBlock(); // Implicit block around while loop. |
| 4875 | 4898 |
| 4876 // Generate implicit iterator variable and add to scope. | 4899 // Generate implicit iterator variable and add to scope. |
| 4877 const String& iterator_name = | 4900 const String& iterator_name = |
| 4878 String::ZoneHandle(String::NewSymbol(":for-in-iter")); | 4901 String::ZoneHandle(String::NewSymbol(":for-in-iter")); |
| 4879 // We could set the type of the implicit iterator variable to Iterator<T> | 4902 // We could set the type of the implicit iterator variable to Iterator<T> |
| 4880 // where T is the type of the for loop variable. However, the type error | 4903 // where T is the type of the for loop variable. However, the type error |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4952 AstNode* while_statement = | 4975 AstNode* while_statement = |
| 4953 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); | 4976 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); |
| 4954 current_block_->statements->Add(while_statement); | 4977 current_block_->statements->Add(while_statement); |
| 4955 | 4978 |
| 4956 return CloseBlock(); // Implicit block around while loop. | 4979 return CloseBlock(); // Implicit block around while loop. |
| 4957 } | 4980 } |
| 4958 | 4981 |
| 4959 | 4982 |
| 4960 AstNode* Parser::ParseForStatement(String* label_name) { | 4983 AstNode* Parser::ParseForStatement(String* label_name) { |
| 4961 TRACE_PARSER("ParseForStatement"); | 4984 TRACE_PARSER("ParseForStatement"); |
| 4962 const intptr_t for_pos = token_index_; | 4985 const intptr_t for_pos = TokenIndex(); |
| 4963 ConsumeToken(); | 4986 ConsumeToken(); |
| 4964 ExpectToken(Token::kLPAREN); | 4987 ExpectToken(Token::kLPAREN); |
| 4965 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 4988 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
| 4966 if (IsForInStatement()) { | 4989 if (IsForInStatement()) { |
| 4967 return ParseForInStatement(for_pos, label); | 4990 return ParseForInStatement(for_pos, label); |
| 4968 } | 4991 } |
| 4969 OpenBlock(); | 4992 OpenBlock(); |
| 4970 // The label is added to the implicit scope that also contains | 4993 // The label is added to the implicit scope that also contains |
| 4971 // the loop variable declarations. | 4994 // the loop variable declarations. |
| 4972 current_block_->scope->AddLabel(label); | 4995 current_block_->scope->AddLabel(label); |
| 4973 AstNode* initializer = NULL; | 4996 AstNode* initializer = NULL; |
| 4974 const intptr_t init_pos = token_index_; | 4997 const intptr_t init_pos = TokenIndex(); |
| 4975 LocalScope* init_scope = current_block_->scope; | 4998 LocalScope* init_scope = current_block_->scope; |
| 4976 if (CurrentToken() != Token::kSEMICOLON) { | 4999 if (CurrentToken() != Token::kSEMICOLON) { |
| 4977 if (IsVariableDeclaration()) { | 5000 if (IsVariableDeclaration()) { |
| 4978 initializer = ParseVariableDeclarationList(); | 5001 initializer = ParseVariableDeclarationList(); |
| 4979 } else { | 5002 } else { |
| 4980 initializer = ParseExpr(kAllowConst); | 5003 initializer = ParseExpr(kAllowConst); |
| 4981 } | 5004 } |
| 4982 } | 5005 } |
| 4983 ExpectSemicolon(); | 5006 ExpectSemicolon(); |
| 4984 AstNode* condition = NULL; | 5007 AstNode* condition = NULL; |
| 4985 if (CurrentToken() != Token::kSEMICOLON) { | 5008 if (CurrentToken() != Token::kSEMICOLON) { |
| 4986 condition = ParseExpr(kAllowConst); | 5009 condition = ParseExpr(kAllowConst); |
| 4987 } | 5010 } |
| 4988 ExpectSemicolon(); | 5011 ExpectSemicolon(); |
| 4989 AstNode* increment = NULL; | 5012 AstNode* increment = NULL; |
| 4990 const intptr_t incr_pos = token_index_; | 5013 const intptr_t incr_pos = TokenIndex(); |
| 4991 LocalScope* incr_scope = current_block_->scope; | 5014 LocalScope* incr_scope = current_block_->scope; |
| 4992 if (CurrentToken() != Token::kRPAREN) { | 5015 if (CurrentToken() != Token::kRPAREN) { |
| 4993 increment = ParseExprList(); | 5016 increment = ParseExprList(); |
| 4994 } | 5017 } |
| 4995 ExpectToken(Token::kRPAREN); | 5018 ExpectToken(Token::kRPAREN); |
| 4996 const bool parsing_loop_body = true; | 5019 const bool parsing_loop_body = true; |
| 4997 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); | 5020 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); |
| 4998 | 5021 |
| 4999 // Check whether any of the variables in the initializer part of | 5022 // Check whether any of the variables in the initializer part of |
| 5000 // the for statement are captured by a closure. If so, we insert a | 5023 // the for statement are captured by a closure. If so, we insert a |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5068 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 5091 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
| 5069 } | 5092 } |
| 5070 return condition; | 5093 return condition; |
| 5071 } | 5094 } |
| 5072 | 5095 |
| 5073 | 5096 |
| 5074 AstNode* Parser::ParseAssertStatement() { | 5097 AstNode* Parser::ParseAssertStatement() { |
| 5075 TRACE_PARSER("ParseAssertStatement"); | 5098 TRACE_PARSER("ParseAssertStatement"); |
| 5076 ConsumeToken(); // Consume assert keyword. | 5099 ConsumeToken(); // Consume assert keyword. |
| 5077 ExpectToken(Token::kLPAREN); | 5100 ExpectToken(Token::kLPAREN); |
| 5078 const intptr_t condition_pos = token_index_; | 5101 const intptr_t condition_pos = TokenIndex(); |
| 5079 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 5102 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { |
| 5080 SkipExpr(); | 5103 SkipExpr(); |
| 5081 ExpectToken(Token::kRPAREN); | 5104 ExpectToken(Token::kRPAREN); |
| 5082 return NULL; | 5105 return NULL; |
| 5083 } | 5106 } |
| 5084 AstNode* condition = ParseExpr(kAllowConst); | 5107 AstNode* condition = ParseExpr(kAllowConst); |
| 5085 const intptr_t condition_end = token_index_; | 5108 const intptr_t condition_end = TokenIndex(); |
| 5086 ExpectToken(Token::kRPAREN); | 5109 ExpectToken(Token::kRPAREN); |
| 5087 condition = InsertClosureCallNodes(condition); | 5110 condition = InsertClosureCallNodes(condition); |
| 5088 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); | 5111 condition = new UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 5089 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 5112 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| 5090 return new IfNode(condition_pos, | 5113 return new IfNode(condition_pos, |
| 5091 condition, | 5114 condition, |
| 5092 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 5115 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
| 5093 NULL); | 5116 NULL); |
| 5094 } | 5117 } |
| 5095 | 5118 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 5106 | 5129 |
| 5107 // Parse the parameter specified in the catch clause. | 5130 // Parse the parameter specified in the catch clause. |
| 5108 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { | 5131 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { |
| 5109 TRACE_PARSER("ParseCatchParameter"); | 5132 TRACE_PARSER("ParseCatchParameter"); |
| 5110 ASSERT(catch_param != NULL); | 5133 ASSERT(catch_param != NULL); |
| 5111 catch_param->is_final = (CurrentToken() == Token::kFINAL); | 5134 catch_param->is_final = (CurrentToken() == Token::kFINAL); |
| 5112 // The type of the catch parameter must always be resolved, even in unchecked | 5135 // The type of the catch parameter must always be resolved, even in unchecked |
| 5113 // mode. | 5136 // mode. |
| 5114 catch_param->type = &AbstractType::ZoneHandle( | 5137 catch_param->type = &AbstractType::ZoneHandle( |
| 5115 ParseFinalVarOrType(ClassFinalizer::kFinalizeWellFormed)); | 5138 ParseFinalVarOrType(ClassFinalizer::kFinalizeWellFormed)); |
| 5116 catch_param->token_index = token_index_; | 5139 catch_param->token_index = TokenIndex(); |
| 5117 catch_param->var = ExpectIdentifier("identifier expected"); | 5140 catch_param->var = ExpectIdentifier("identifier expected"); |
| 5118 } | 5141 } |
| 5119 | 5142 |
| 5120 | 5143 |
| 5121 // Populate local scope of the catch block with the catch parameters. | 5144 // Populate local scope of the catch block with the catch parameters. |
| 5122 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 5145 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
| 5123 const CatchParamDesc& stack_trace_param, | 5146 const CatchParamDesc& stack_trace_param, |
| 5124 LocalScope* scope) { | 5147 LocalScope* scope) { |
| 5125 ASSERT(exception_param.var != NULL); | 5148 ASSERT(exception_param.var != NULL); |
| 5126 LocalVariable* var = new LocalVariable(exception_param.token_index, | 5149 LocalVariable* var = new LocalVariable(exception_param.token_index, |
| 5127 *exception_param.var, | 5150 *exception_param.var, |
| 5128 *exception_param.type); | 5151 *exception_param.type); |
| 5129 if (exception_param.is_final) { | 5152 if (exception_param.is_final) { |
| 5130 var->set_is_final(); | 5153 var->set_is_final(); |
| 5131 } | 5154 } |
| 5132 bool added_to_scope = scope->AddVariable(var); | 5155 bool added_to_scope = scope->AddVariable(var); |
| 5133 ASSERT(added_to_scope); | 5156 ASSERT(added_to_scope); |
| 5134 if (stack_trace_param.var != NULL) { | 5157 if (stack_trace_param.var != NULL) { |
| 5135 var = new LocalVariable(token_index_, | 5158 var = new LocalVariable(TokenIndex(), |
| 5136 *stack_trace_param.var, | 5159 *stack_trace_param.var, |
| 5137 *stack_trace_param.type); | 5160 *stack_trace_param.type); |
| 5138 if (stack_trace_param.is_final) { | 5161 if (stack_trace_param.is_final) { |
| 5139 var->set_is_final(); | 5162 var->set_is_final(); |
| 5140 } | 5163 } |
| 5141 added_to_scope = scope->AddVariable(var); | 5164 added_to_scope = scope->AddVariable(var); |
| 5142 if (!added_to_scope) { | 5165 if (!added_to_scope) { |
| 5143 ErrorMsg(stack_trace_param.token_index, | 5166 ErrorMsg(stack_trace_param.token_index, |
| 5144 "name '%s' already exists in scope", | 5167 "name '%s' already exists in scope", |
| 5145 stack_trace_param.var->ToCString()); | 5168 stack_trace_param.var->ToCString()); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5224 // the stack trace was copied into when an exception was | 5247 // the stack trace was copied into when an exception was |
| 5225 // thrown. | 5248 // thrown. |
| 5226 // :exception_var and :stacktrace_var get set with the exception object | 5249 // :exception_var and :stacktrace_var get set with the exception object |
| 5227 // and the stacktrace object when an exception is thrown. | 5250 // and the stacktrace object when an exception is thrown. |
| 5228 // These three implicit variables can never be captured variables. | 5251 // These three implicit variables can never be captured variables. |
| 5229 const String& context_var_name = | 5252 const String& context_var_name = |
| 5230 String::ZoneHandle(String::NewSymbol(":saved_context_var")); | 5253 String::ZoneHandle(String::NewSymbol(":saved_context_var")); |
| 5231 LocalVariable* context_var = | 5254 LocalVariable* context_var = |
| 5232 current_block_->scope->LocalLookupVariable(context_var_name); | 5255 current_block_->scope->LocalLookupVariable(context_var_name); |
| 5233 if (context_var == NULL) { | 5256 if (context_var == NULL) { |
| 5234 context_var = new LocalVariable(token_index_, | 5257 context_var = new LocalVariable(TokenIndex(), |
| 5235 context_var_name, | 5258 context_var_name, |
| 5236 Type::ZoneHandle(Type::DynamicType())); | 5259 Type::ZoneHandle(Type::DynamicType())); |
| 5237 current_block_->scope->AddVariable(context_var); | 5260 current_block_->scope->AddVariable(context_var); |
| 5238 } | 5261 } |
| 5239 const String& catch_excp_var_name = | 5262 const String& catch_excp_var_name = |
| 5240 String::ZoneHandle(String::NewSymbol(":exception_var")); | 5263 String::ZoneHandle(String::NewSymbol(":exception_var")); |
| 5241 LocalVariable* catch_excp_var = | 5264 LocalVariable* catch_excp_var = |
| 5242 current_block_->scope->LocalLookupVariable(catch_excp_var_name); | 5265 current_block_->scope->LocalLookupVariable(catch_excp_var_name); |
| 5243 if (catch_excp_var == NULL) { | 5266 if (catch_excp_var == NULL) { |
| 5244 catch_excp_var = new LocalVariable(token_index_, | 5267 catch_excp_var = new LocalVariable(TokenIndex(), |
| 5245 catch_excp_var_name, | 5268 catch_excp_var_name, |
| 5246 Type::ZoneHandle(Type::DynamicType())); | 5269 Type::ZoneHandle(Type::DynamicType())); |
| 5247 current_block_->scope->AddVariable(catch_excp_var); | 5270 current_block_->scope->AddVariable(catch_excp_var); |
| 5248 } | 5271 } |
| 5249 const String& catch_trace_var_name = | 5272 const String& catch_trace_var_name = |
| 5250 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); | 5273 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); |
| 5251 LocalVariable* catch_trace_var = | 5274 LocalVariable* catch_trace_var = |
| 5252 current_block_->scope->LocalLookupVariable(catch_trace_var_name); | 5275 current_block_->scope->LocalLookupVariable(catch_trace_var_name); |
| 5253 if (catch_trace_var == NULL) { | 5276 if (catch_trace_var == NULL) { |
| 5254 catch_trace_var = new LocalVariable(token_index_, | 5277 catch_trace_var = new LocalVariable(TokenIndex(), |
| 5255 catch_trace_var_name, | 5278 catch_trace_var_name, |
| 5256 Type::ZoneHandle(Type::DynamicType())); | 5279 Type::ZoneHandle(Type::DynamicType())); |
| 5257 current_block_->scope->AddVariable(catch_trace_var); | 5280 current_block_->scope->AddVariable(catch_trace_var); |
| 5258 } | 5281 } |
| 5259 | 5282 |
| 5260 const intptr_t try_pos = token_index_; | 5283 const intptr_t try_pos = TokenIndex(); |
| 5261 ConsumeToken(); // Consume the 'try'. | 5284 ConsumeToken(); // Consume the 'try'. |
| 5262 | 5285 |
| 5263 SourceLabel* try_label = NULL; | 5286 SourceLabel* try_label = NULL; |
| 5264 if (label_name != NULL) { | 5287 if (label_name != NULL) { |
| 5265 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 5288 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 5266 OpenBlock(); | 5289 OpenBlock(); |
| 5267 current_block_->scope->AddLabel(try_label); | 5290 current_block_->scope->AddLabel(try_label); |
| 5268 } | 5291 } |
| 5269 | 5292 |
| 5270 // Now parse the 'try' block. | 5293 // Now parse the 'try' block. |
| 5271 OpenBlock(); | 5294 OpenBlock(); |
| 5272 Block* current_try_block = current_block_; | 5295 Block* current_try_block = current_block_; |
| 5273 PushTryBlock(current_try_block); | 5296 PushTryBlock(current_try_block); |
| 5274 ExpectToken(Token::kLBRACE); | 5297 ExpectToken(Token::kLBRACE); |
| 5275 ParseStatementSequence(); | 5298 ParseStatementSequence(); |
| 5276 ExpectToken(Token::kRBRACE); | 5299 ExpectToken(Token::kRBRACE); |
| 5277 SequenceNode* try_block = CloseBlock(); | 5300 SequenceNode* try_block = CloseBlock(); |
| 5278 | 5301 |
| 5279 // Now create a label for the end of catch block processing so that we can | 5302 // Now create a label for the end of catch block processing so that we can |
| 5280 // jump over the catch block code after executing the try block. | 5303 // jump over the catch block code after executing the try block. |
| 5281 SourceLabel* end_catch_label = | 5304 SourceLabel* end_catch_label = |
| 5282 SourceLabel::New(token_index_, NULL, SourceLabel::kCatch); | 5305 SourceLabel::New(TokenIndex(), NULL, SourceLabel::kCatch); |
| 5283 | 5306 |
| 5284 // Now parse the 'catch' blocks if any and merge all of them into | 5307 // Now parse the 'catch' blocks if any and merge all of them into |
| 5285 // an if-then sequence of the different types specified using the 'is' | 5308 // an if-then sequence of the different types specified using the 'is' |
| 5286 // operator. | 5309 // operator. |
| 5287 bool catch_seen = false; | 5310 bool catch_seen = false; |
| 5288 bool generic_catch_seen = false; | 5311 bool generic_catch_seen = false; |
| 5289 SequenceNode* catch_handler_list = NULL; | 5312 SequenceNode* catch_handler_list = NULL; |
| 5290 const intptr_t handler_pos = token_index_; | 5313 const intptr_t handler_pos = TokenIndex(); |
| 5291 OpenBlock(); // Start the catch block sequence. | 5314 OpenBlock(); // Start the catch block sequence. |
| 5292 current_block_->scope->AddLabel(end_catch_label); | 5315 current_block_->scope->AddLabel(end_catch_label); |
| 5293 while (CurrentToken() == Token::kCATCH) { | 5316 while (CurrentToken() == Token::kCATCH) { |
| 5294 catch_seen = true; | 5317 catch_seen = true; |
| 5295 const intptr_t catch_pos = token_index_; | 5318 const intptr_t catch_pos = TokenIndex(); |
| 5296 ConsumeToken(); // Consume the 'catch'. | 5319 ConsumeToken(); // Consume the 'catch'. |
| 5297 ExpectToken(Token::kLPAREN); | 5320 ExpectToken(Token::kLPAREN); |
| 5298 CatchParamDesc exception_param; | 5321 CatchParamDesc exception_param; |
| 5299 CatchParamDesc stack_trace_param; | 5322 CatchParamDesc stack_trace_param; |
| 5300 ParseCatchParameter(&exception_param); | 5323 ParseCatchParameter(&exception_param); |
| 5301 if (CurrentToken() == Token::kCOMMA) { | 5324 if (CurrentToken() == Token::kCOMMA) { |
| 5302 ConsumeToken(); | 5325 ConsumeToken(); |
| 5303 ParseCatchParameter(&stack_trace_param); | 5326 ParseCatchParameter(&stack_trace_param); |
| 5304 } | 5327 } |
| 5305 ExpectToken(Token::kRPAREN); | 5328 ExpectToken(Token::kRPAREN); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5380 current_block_->statements->Add(catch_clause); | 5403 current_block_->statements->Add(catch_clause); |
| 5381 } | 5404 } |
| 5382 catch_handler_list = CloseBlock(); | 5405 catch_handler_list = CloseBlock(); |
| 5383 TryBlocks* inner_try_block = PopTryBlock(); | 5406 TryBlocks* inner_try_block = PopTryBlock(); |
| 5384 | 5407 |
| 5385 // Finally parse the 'finally' block. | 5408 // Finally parse the 'finally' block. |
| 5386 SequenceNode* finally_block = NULL; | 5409 SequenceNode* finally_block = NULL; |
| 5387 if (CurrentToken() == Token::kFINALLY) { | 5410 if (CurrentToken() == Token::kFINALLY) { |
| 5388 current_function_.set_is_optimizable(false); | 5411 current_function_.set_is_optimizable(false); |
| 5389 ConsumeToken(); // Consume the 'finally'. | 5412 ConsumeToken(); // Consume the 'finally'. |
| 5390 const intptr_t finally_pos = token_index_; | 5413 const intptr_t finally_pos = TokenIndex(); |
| 5391 // Add the finally block to the exit points recorded so far. | 5414 // Add the finally block to the exit points recorded so far. |
| 5392 intptr_t node_index = 0; | 5415 intptr_t node_index = 0; |
| 5393 AstNode* node_to_inline = | 5416 AstNode* node_to_inline = |
| 5394 inner_try_block->GetNodeToInlineFinally(node_index); | 5417 inner_try_block->GetNodeToInlineFinally(node_index); |
| 5395 while (node_to_inline != NULL) { | 5418 while (node_to_inline != NULL) { |
| 5396 finally_block = ParseFinallyBlock(); | 5419 finally_block = ParseFinallyBlock(); |
| 5397 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, | 5420 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, |
| 5398 finally_block, | 5421 finally_block, |
| 5399 *context_var); | 5422 *context_var); |
| 5400 AddFinallyBlockToNode(node_to_inline, node); | 5423 AddFinallyBlockToNode(node_to_inline, node); |
| 5401 node_index += 1; | 5424 node_index += 1; |
| 5402 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); | 5425 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); |
| 5403 token_index_ = finally_pos; | 5426 tokens_iterator_.SetCurrentIndex(finally_pos); |
| 5404 } | 5427 } |
| 5405 if (!generic_catch_seen) { | 5428 if (!generic_catch_seen) { |
| 5406 // No generic catch handler exists so execute this finally block | 5429 // No generic catch handler exists so execute this finally block |
| 5407 // before rethrowing the exception. | 5430 // before rethrowing the exception. |
| 5408 finally_block = ParseFinallyBlock(); | 5431 finally_block = ParseFinallyBlock(); |
| 5409 catch_handler_list->Add(finally_block); | 5432 catch_handler_list->Add(finally_block); |
| 5410 token_index_ = finally_pos; | 5433 tokens_iterator_.SetCurrentIndex(finally_pos); |
| 5411 } | 5434 } |
| 5412 finally_block = ParseFinallyBlock(); | 5435 finally_block = ParseFinallyBlock(); |
| 5413 } else { | 5436 } else { |
| 5414 if (!catch_seen) { | 5437 if (!catch_seen) { |
| 5415 ErrorMsg("'catch' or 'finally' expected"); | 5438 ErrorMsg("'catch' or 'finally' expected"); |
| 5416 } | 5439 } |
| 5417 } | 5440 } |
| 5418 | 5441 |
| 5419 if (!generic_catch_seen) { | 5442 if (!generic_catch_seen) { |
| 5420 // No generic catch handler exists so rethrow the exception so that | 5443 // No generic catch handler exists so rethrow the exception so that |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 5444 try_catch_node = sequence; | 5467 try_catch_node = sequence; |
| 5445 } | 5468 } |
| 5446 return try_catch_node; | 5469 return try_catch_node; |
| 5447 } | 5470 } |
| 5448 | 5471 |
| 5449 | 5472 |
| 5450 AstNode* Parser::ParseJump(String* label_name) { | 5473 AstNode* Parser::ParseJump(String* label_name) { |
| 5451 TRACE_PARSER("ParseJump"); | 5474 TRACE_PARSER("ParseJump"); |
| 5452 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 5475 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 5453 Token::Kind jump_kind = CurrentToken(); | 5476 Token::Kind jump_kind = CurrentToken(); |
| 5454 const intptr_t jump_pos = token_index_; | 5477 const intptr_t jump_pos = TokenIndex(); |
| 5455 SourceLabel* target = NULL; | 5478 SourceLabel* target = NULL; |
| 5456 ConsumeToken(); | 5479 ConsumeToken(); |
| 5457 if (IsIdentifier()) { | 5480 if (IsIdentifier()) { |
| 5458 // Explicit label after break/continue. | 5481 // Explicit label after break/continue. |
| 5459 const String& target_name = *CurrentLiteral(); | 5482 const String& target_name = *CurrentLiteral(); |
| 5460 ConsumeToken(); | 5483 ConsumeToken(); |
| 5461 // Handle pathological cases first. | 5484 // Handle pathological cases first. |
| 5462 if (label_name != NULL && target_name.Equals(*label_name)) { | 5485 if (label_name != NULL && target_name.Equals(*label_name)) { |
| 5463 if (jump_kind == Token::kCONTINUE) { | 5486 if (jump_kind == Token::kCONTINUE) { |
| 5464 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 5487 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", |
| 5465 target_name.ToCString()); | 5488 target_name.ToCString()); |
| 5466 } | 5489 } |
| 5467 // L: break L; is a no-op. | 5490 // L: break L; is a no-op. |
| 5468 return NULL; | 5491 return NULL; |
| 5469 } | 5492 } |
| 5470 target = current_block_->scope->LookupLabel(target_name); | 5493 target = current_block_->scope->LookupLabel(target_name); |
| 5471 if (target == NULL && jump_kind == Token::kCONTINUE) { | 5494 if (target == NULL && jump_kind == Token::kCONTINUE) { |
| 5472 // Either a reference to a non-existent label, or a forward reference | 5495 // Either a reference to a non-existent label, or a forward reference |
| 5473 // to a case label that we haven't seen yet. If we are inside a switch | 5496 // to a case label that we haven't seen yet. If we are inside a switch |
| 5474 // statement, create a "forward reference" label in the scope of | 5497 // statement, create a "forward reference" label in the scope of |
| 5475 // the switch statement. | 5498 // the switch statement. |
| 5476 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); | 5499 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); |
| 5477 if (switch_scope != NULL) { | 5500 if (switch_scope != NULL) { |
| 5478 // We found a switch scope. Enter a forward reference to the label. | 5501 // We found a switch scope. Enter a forward reference to the label. |
| 5479 target = new SourceLabel( | 5502 target = new SourceLabel( |
| 5480 token_index_, target_name, SourceLabel::kForward); | 5503 TokenIndex(), target_name, SourceLabel::kForward); |
| 5481 switch_scope->AddLabel(target); | 5504 switch_scope->AddLabel(target); |
| 5482 } | 5505 } |
| 5483 } | 5506 } |
| 5484 if (target == NULL) { | 5507 if (target == NULL) { |
| 5485 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); | 5508 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); |
| 5486 } | 5509 } |
| 5487 } else { | 5510 } else { |
| 5488 target = current_block_->scope->LookupInnermostLabel(jump_kind); | 5511 target = current_block_->scope->LookupInnermostLabel(jump_kind); |
| 5489 if (target == NULL) { | 5512 if (target == NULL) { |
| 5490 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); | 5513 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 5504 } | 5527 } |
| 5505 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 5528 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 5506 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 5529 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
| 5507 Token::Str(jump_kind)); | 5530 Token::Str(jump_kind)); |
| 5508 } | 5531 } |
| 5509 return new JumpNode(jump_pos, jump_kind, target); | 5532 return new JumpNode(jump_pos, jump_kind, target); |
| 5510 } | 5533 } |
| 5511 | 5534 |
| 5512 | 5535 |
| 5513 bool Parser::IsDefinedInLexicalScope(const String& ident) { | 5536 bool Parser::IsDefinedInLexicalScope(const String& ident) { |
| 5514 if (ResolveIdentInLocalScope(token_index_, ident, NULL)) { | 5537 if (ResolveIdentInLocalScope(TokenIndex(), ident, NULL)) { |
| 5515 return true; | 5538 return true; |
| 5516 } | 5539 } |
| 5517 Object& obj = Object::Handle(); | 5540 Object& obj = Object::Handle(); |
| 5518 obj = library_.LookupObject(ident); | 5541 obj = library_.LookupObject(ident); |
| 5519 return !obj.IsNull(); | 5542 return !obj.IsNull(); |
| 5520 } | 5543 } |
| 5521 | 5544 |
| 5522 | 5545 |
| 5523 AstNode* Parser::ParseStatement() { | 5546 AstNode* Parser::ParseStatement() { |
| 5524 TRACE_PARSER("ParseStatement"); | 5547 TRACE_PARSER("ParseStatement"); |
| 5525 AstNode* statement = NULL; | 5548 AstNode* statement = NULL; |
| 5526 intptr_t label_pos = 0; | 5549 intptr_t label_pos = 0; |
| 5527 String* label_name = NULL; | 5550 String* label_name = NULL; |
| 5528 if (IsIdentifier()) { | 5551 if (IsIdentifier()) { |
| 5529 if (LookaheadToken(1) == Token::kCOLON) { | 5552 if (LookaheadToken(1) == Token::kCOLON) { |
| 5530 // Statement starts with a label. | 5553 // Statement starts with a label. |
| 5531 label_name = CurrentLiteral(); | 5554 label_name = CurrentLiteral(); |
| 5532 label_pos = token_index_; | 5555 label_pos = TokenIndex(); |
| 5533 ASSERT(label_pos > 0); | 5556 ASSERT(label_pos > 0); |
| 5534 ConsumeToken(); // Consume identifier. | 5557 ConsumeToken(); // Consume identifier. |
| 5535 ConsumeToken(); // Consume colon. | 5558 ConsumeToken(); // Consume colon. |
| 5536 } | 5559 } |
| 5537 } | 5560 } |
| 5538 const intptr_t statement_pos = token_index_; | 5561 const intptr_t statement_pos = TokenIndex(); |
| 5539 | 5562 |
| 5540 if (CurrentToken() == Token::kWHILE) { | 5563 if (CurrentToken() == Token::kWHILE) { |
| 5541 statement = ParseWhileStatement(label_name); | 5564 statement = ParseWhileStatement(label_name); |
| 5542 } else if (CurrentToken() == Token::kFOR) { | 5565 } else if (CurrentToken() == Token::kFOR) { |
| 5543 statement = ParseForStatement(label_name); | 5566 statement = ParseForStatement(label_name); |
| 5544 } else if (CurrentToken() == Token::kDO) { | 5567 } else if (CurrentToken() == Token::kDO) { |
| 5545 statement = ParseDoWhileStatement(label_name); | 5568 statement = ParseDoWhileStatement(label_name); |
| 5546 } else if (CurrentToken() == Token::kSWITCH) { | 5569 } else if (CurrentToken() == Token::kSWITCH) { |
| 5547 statement = ParseSwitchStatement(label_name); | 5570 statement = ParseSwitchStatement(label_name); |
| 5548 } else if (CurrentToken() == Token::kTRY) { | 5571 } else if (CurrentToken() == Token::kTRY) { |
| 5549 statement = ParseTryStatement(label_name); | 5572 statement = ParseTryStatement(label_name); |
| 5550 } else if (CurrentToken() == Token::kRETURN) { | 5573 } else if (CurrentToken() == Token::kRETURN) { |
| 5551 const intptr_t return_pos = token_index_; | 5574 const intptr_t return_pos = TokenIndex(); |
| 5552 ConsumeToken(); | 5575 ConsumeToken(); |
| 5553 if (CurrentToken() != Token::kSEMICOLON) { | 5576 if (CurrentToken() != Token::kSEMICOLON) { |
| 5554 if (current_function().IsConstructor() && | 5577 if (current_function().IsConstructor() && |
| 5555 (current_block_->scope->function_level() == 0)) { | 5578 (current_block_->scope->function_level() == 0)) { |
| 5556 ErrorMsg(return_pos, "return of a value not allowed in constructors"); | 5579 ErrorMsg(return_pos, "return of a value not allowed in constructors"); |
| 5557 } | 5580 } |
| 5558 AstNode* expr = ParseExpr(kAllowConst); | 5581 AstNode* expr = ParseExpr(kAllowConst); |
| 5559 statement = new ReturnNode(statement_pos, expr); | 5582 statement = new ReturnNode(statement_pos, expr); |
| 5560 } else { | 5583 } else { |
| 5561 statement = new ReturnNode(statement_pos); | 5584 statement = new ReturnNode(statement_pos); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5736 va_end(args); | 5759 va_end(args); |
| 5737 Isolate::Current()->long_jump_base()->Jump(1, error); | 5760 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5738 UNREACHABLE(); | 5761 UNREACHABLE(); |
| 5739 } | 5762 } |
| 5740 | 5763 |
| 5741 | 5764 |
| 5742 void Parser::ErrorMsg(const char* format, ...) { | 5765 void Parser::ErrorMsg(const char* format, ...) { |
| 5743 va_list args; | 5766 va_list args; |
| 5744 va_start(args, format); | 5767 va_start(args, format); |
| 5745 const Error& error = Error::Handle( | 5768 const Error& error = Error::Handle( |
| 5746 FormatError(script_, token_index_, "Error", format, args)); | 5769 FormatError(script_, TokenIndex(), "Error", format, args)); |
| 5747 va_end(args); | 5770 va_end(args); |
| 5748 Isolate::Current()->long_jump_base()->Jump(1, error); | 5771 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5749 UNREACHABLE(); | 5772 UNREACHABLE(); |
| 5750 } | 5773 } |
| 5751 | 5774 |
| 5752 | 5775 |
| 5753 void Parser::ErrorMsg(const Error& error) { | 5776 void Parser::ErrorMsg(const Error& error) { |
| 5754 Isolate::Current()->long_jump_base()->Jump(1, error); | 5777 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5755 UNREACHABLE(); | 5778 UNREACHABLE(); |
| 5756 } | 5779 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 5782 OS::Print("%s", error.ToErrorCString()); | 5805 OS::Print("%s", error.ToErrorCString()); |
| 5783 } | 5806 } |
| 5784 } | 5807 } |
| 5785 | 5808 |
| 5786 | 5809 |
| 5787 void Parser::Warning(const char* format, ...) { | 5810 void Parser::Warning(const char* format, ...) { |
| 5788 if (FLAG_silent_warnings) return; | 5811 if (FLAG_silent_warnings) return; |
| 5789 va_list args; | 5812 va_list args; |
| 5790 va_start(args, format); | 5813 va_start(args, format); |
| 5791 const Error& error = Error::Handle( | 5814 const Error& error = Error::Handle( |
| 5792 FormatError(script_, token_index_, "Warning", format, args)); | 5815 FormatError(script_, TokenIndex(), "Warning", format, args)); |
| 5793 va_end(args); | 5816 va_end(args); |
| 5794 if (FLAG_warning_as_error) { | 5817 if (FLAG_warning_as_error) { |
| 5795 Isolate::Current()->long_jump_base()->Jump(1, error); | 5818 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 5796 UNREACHABLE(); | 5819 UNREACHABLE(); |
| 5797 } else { | 5820 } else { |
| 5798 OS::Print("%s", error.ToErrorCString()); | 5821 OS::Print("%s", error.ToErrorCString()); |
| 5799 } | 5822 } |
| 5800 } | 5823 } |
| 5801 | 5824 |
| 5802 | 5825 |
| 5803 void Parser::Unimplemented(const char* msg) { | 5826 void Parser::Unimplemented(const char* msg) { |
| 5804 ErrorMsg(token_index_, msg); | 5827 ErrorMsg(TokenIndex(), msg); |
| 5805 } | 5828 } |
| 5806 | 5829 |
| 5807 | 5830 |
| 5808 void Parser::ExpectToken(Token::Kind token_expected) { | 5831 void Parser::ExpectToken(Token::Kind token_expected) { |
| 5809 if (CurrentToken() != token_expected) { | 5832 if (CurrentToken() != token_expected) { |
| 5810 ErrorMsg("'%s' expected", Token::Str(token_expected)); | 5833 ErrorMsg("'%s' expected", Token::Str(token_expected)); |
| 5811 } | 5834 } |
| 5812 ConsumeToken(); | 5835 ConsumeToken(); |
| 5813 } | 5836 } |
| 5814 | 5837 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5908 TRACE_PARSER("ParseBinaryExpr"); | 5931 TRACE_PARSER("ParseBinaryExpr"); |
| 5909 ASSERT(min_preced >= 4); | 5932 ASSERT(min_preced >= 4); |
| 5910 AstNode* left_operand = ParseUnaryExpr(); | 5933 AstNode* left_operand = ParseUnaryExpr(); |
| 5911 int current_preced = Token::Precedence(CurrentToken()); | 5934 int current_preced = Token::Precedence(CurrentToken()); |
| 5912 while (current_preced >= min_preced) { | 5935 while (current_preced >= min_preced) { |
| 5913 while (Token::Precedence(CurrentToken()) == current_preced) { | 5936 while (Token::Precedence(CurrentToken()) == current_preced) { |
| 5914 Token::Kind op_kind = CurrentToken(); | 5937 Token::Kind op_kind = CurrentToken(); |
| 5915 if (op_kind == Token::kTIGHTADD) { | 5938 if (op_kind == Token::kTIGHTADD) { |
| 5916 op_kind = Token::kADD; | 5939 op_kind = Token::kADD; |
| 5917 } | 5940 } |
| 5918 const intptr_t op_pos = token_index_; | 5941 const intptr_t op_pos = TokenIndex(); |
| 5919 ConsumeToken(); | 5942 ConsumeToken(); |
| 5920 AstNode* right_operand = NULL; | 5943 AstNode* right_operand = NULL; |
| 5921 if (op_kind != Token::kIS) { | 5944 if (op_kind != Token::kIS) { |
| 5922 right_operand = ParseBinaryExpr(current_preced + 1); | 5945 right_operand = ParseBinaryExpr(current_preced + 1); |
| 5923 } else { | 5946 } else { |
| 5924 // For 'is' we expect the right operand to be a type. | 5947 // For 'is' we expect the right operand to be a type. |
| 5925 if (CurrentToken() == Token::kNOT) { | 5948 if (CurrentToken() == Token::kNOT) { |
| 5926 ConsumeToken(); | 5949 ConsumeToken(); |
| 5927 op_kind = Token::kISNOT; | 5950 op_kind = Token::kISNOT; |
| 5928 } | 5951 } |
| 5929 const intptr_t type_pos = token_index_; | 5952 const intptr_t type_pos = TokenIndex(); |
| 5930 const AbstractType& type = | 5953 const AbstractType& type = |
| 5931 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); | 5954 AbstractType::ZoneHandle(ParseType(ClassFinalizer::kFinalize)); |
| 5932 if (!type.IsInstantiated() && | 5955 if (!type.IsInstantiated() && |
| 5933 (current_block_->scope->function_level() > 0)) { | 5956 (current_block_->scope->function_level() > 0)) { |
| 5934 // Make sure that the instantiator is captured. | 5957 // Make sure that the instantiator is captured. |
| 5935 CaptureReceiver(); | 5958 CaptureReceiver(); |
| 5936 } | 5959 } |
| 5937 right_operand = new TypeNode(type_pos, type); | 5960 right_operand = new TypeNode(type_pos, type); |
| 5938 if (type.IsMalformed()) { | 5961 if (type.IsMalformed()) { |
| 5939 // Note that a type error is thrown even if the tested value is null. | 5962 // Note that a type error is thrown even if the tested value is null. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 5970 || expr->IsInstanceGetterNode() | 5993 || expr->IsInstanceGetterNode() |
| 5971 || expr->IsLoadIndexedNode(); | 5994 || expr->IsLoadIndexedNode(); |
| 5972 } | 5995 } |
| 5973 | 5996 |
| 5974 | 5997 |
| 5975 AstNode* Parser::ParseExprList() { | 5998 AstNode* Parser::ParseExprList() { |
| 5976 TRACE_PARSER("ParseExprList"); | 5999 TRACE_PARSER("ParseExprList"); |
| 5977 AstNode* expressions = ParseExpr(kAllowConst); | 6000 AstNode* expressions = ParseExpr(kAllowConst); |
| 5978 if (CurrentToken() == Token::kCOMMA) { | 6001 if (CurrentToken() == Token::kCOMMA) { |
| 5979 // Collect comma-separated expressions in a non scope owning sequence node. | 6002 // Collect comma-separated expressions in a non scope owning sequence node. |
| 5980 SequenceNode* list = new SequenceNode(token_index_, NULL); | 6003 SequenceNode* list = new SequenceNode(TokenIndex(), NULL); |
| 5981 list->Add(expressions); | 6004 list->Add(expressions); |
| 5982 while (CurrentToken() == Token::kCOMMA) { | 6005 while (CurrentToken() == Token::kCOMMA) { |
| 5983 ConsumeToken(); | 6006 ConsumeToken(); |
| 5984 AstNode* expr = ParseExpr(kAllowConst); | 6007 AstNode* expr = ParseExpr(kAllowConst); |
| 5985 list->Add(expr); | 6008 list->Add(expr); |
| 5986 } | 6009 } |
| 5987 expressions = list; | 6010 expressions = list; |
| 5988 } | 6011 } |
| 5989 return expressions; | 6012 return expressions; |
| 5990 } | 6013 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6171 if ((result != NULL) && | 6194 if ((result != NULL) && |
| 6172 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { | 6195 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { |
| 6173 EnsureExpressionTemp(); | 6196 EnsureExpressionTemp(); |
| 6174 } | 6197 } |
| 6175 return result; | 6198 return result; |
| 6176 } | 6199 } |
| 6177 | 6200 |
| 6178 | 6201 |
| 6179 AstNode* Parser::ParseExpr(bool require_compiletime_const) { | 6202 AstNode* Parser::ParseExpr(bool require_compiletime_const) { |
| 6180 TRACE_PARSER("ParseExpr"); | 6203 TRACE_PARSER("ParseExpr"); |
| 6181 const intptr_t expr_pos = token_index_; | 6204 const intptr_t expr_pos = TokenIndex(); |
| 6182 AstNode* expr = ParseConditionalExpr(); | 6205 AstNode* expr = ParseConditionalExpr(); |
| 6183 if (!Token::IsAssignmentOperator(CurrentToken())) { | 6206 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 6184 if (require_compiletime_const) { | 6207 if (require_compiletime_const) { |
| 6185 expr = FoldConstExpr(expr_pos, expr); | 6208 expr = FoldConstExpr(expr_pos, expr); |
| 6186 } | 6209 } |
| 6187 return expr; | 6210 return expr; |
| 6188 } | 6211 } |
| 6189 // Assignment expressions. | 6212 // Assignment expressions. |
| 6190 Token::Kind assignment_op = CurrentToken(); | 6213 Token::Kind assignment_op = CurrentToken(); |
| 6191 const intptr_t assignment_pos = token_index_; | 6214 const intptr_t assignment_pos = TokenIndex(); |
| 6192 ConsumeToken(); | 6215 ConsumeToken(); |
| 6193 const intptr_t right_expr_pos = token_index_; | 6216 const intptr_t right_expr_pos = TokenIndex(); |
| 6194 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 6217 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 6195 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); | 6218 ErrorMsg(right_expr_pos, "expression must be a compile time constant"); |
| 6196 } | 6219 } |
| 6197 AstNode* right_expr = ParseExpr(require_compiletime_const); | 6220 AstNode* right_expr = ParseExpr(require_compiletime_const); |
| 6198 AstNode* left_expr = expr; | 6221 AstNode* left_expr = expr; |
| 6199 if (assignment_op != Token::kASSIGN) { | 6222 if (assignment_op != Token::kASSIGN) { |
| 6200 // Compound assignment: store inputs with side effects into temp. locals. | 6223 // Compound assignment: store inputs with side effects into temp. locals. |
| 6201 left_expr = PrepareCompoundAssignmentNodes(&expr); | 6224 left_expr = PrepareCompoundAssignmentNodes(&expr); |
| 6202 } | 6225 } |
| 6203 right_expr = | 6226 right_expr = |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 6215 LiteralNode* Parser::ParseConstExpr() { | 6238 LiteralNode* Parser::ParseConstExpr() { |
| 6216 TRACE_PARSER("ParseConstExpr"); | 6239 TRACE_PARSER("ParseConstExpr"); |
| 6217 AstNode* expr = ParseExpr(kRequireConst); | 6240 AstNode* expr = ParseExpr(kRequireConst); |
| 6218 ASSERT(expr->IsLiteralNode()); | 6241 ASSERT(expr->IsLiteralNode()); |
| 6219 return expr->AsLiteralNode(); | 6242 return expr->AsLiteralNode(); |
| 6220 } | 6243 } |
| 6221 | 6244 |
| 6222 | 6245 |
| 6223 AstNode* Parser::ParseConditionalExpr() { | 6246 AstNode* Parser::ParseConditionalExpr() { |
| 6224 TRACE_PARSER("ParseConditionalExpr"); | 6247 TRACE_PARSER("ParseConditionalExpr"); |
| 6225 const intptr_t expr_pos = token_index_; | 6248 const intptr_t expr_pos = TokenIndex(); |
| 6226 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 6249 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
| 6227 if (CurrentToken() == Token::kCONDITIONAL) { | 6250 if (CurrentToken() == Token::kCONDITIONAL) { |
| 6228 EnsureExpressionTemp(); | 6251 EnsureExpressionTemp(); |
| 6229 ConsumeToken(); | 6252 ConsumeToken(); |
| 6230 AstNode* expr1 = ParseExpr(kAllowConst); | 6253 AstNode* expr1 = ParseExpr(kAllowConst); |
| 6231 ExpectToken(Token::kCOLON); | 6254 ExpectToken(Token::kCOLON); |
| 6232 AstNode* expr2 = ParseExpr(kAllowConst); | 6255 AstNode* expr2 = ParseExpr(kAllowConst); |
| 6233 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); | 6256 expr = new ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 6234 } | 6257 } |
| 6235 return expr; | 6258 return expr; |
| 6236 } | 6259 } |
| 6237 | 6260 |
| 6238 | 6261 |
| 6239 AstNode* Parser::ParseUnaryExpr() { | 6262 AstNode* Parser::ParseUnaryExpr() { |
| 6240 TRACE_PARSER("ParseUnaryExpr"); | 6263 TRACE_PARSER("ParseUnaryExpr"); |
| 6241 AstNode* expr = NULL; | 6264 AstNode* expr = NULL; |
| 6242 const intptr_t op_pos = token_index_; | 6265 const intptr_t op_pos = TokenIndex(); |
| 6243 if (IsPrefixOperator(CurrentToken())) { | 6266 if (IsPrefixOperator(CurrentToken())) { |
| 6244 Token::Kind unary_op = CurrentToken(); | 6267 Token::Kind unary_op = CurrentToken(); |
| 6245 ConsumeToken(); | 6268 ConsumeToken(); |
| 6246 expr = ParseUnaryExpr(); | 6269 expr = ParseUnaryExpr(); |
| 6247 if (unary_op == Token::kTIGHTADD) { | 6270 if (unary_op == Token::kTIGHTADD) { |
| 6248 // kTIGHADD is added only in front of a number literal. | 6271 // kTIGHADD is added only in front of a number literal. |
| 6249 if (!expr->IsLiteralNode()) { | 6272 if (!expr->IsLiteralNode()) { |
| 6250 ErrorMsg(op_pos, "unexpected operator '+'"); | 6273 ErrorMsg(op_pos, "unexpected operator '+'"); |
| 6251 } | 6274 } |
| 6252 // Expression is the literal itself. | 6275 // Expression is the literal itself. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 6279 | 6302 |
| 6280 | 6303 |
| 6281 ArgumentListNode* Parser::ParseActualParameters( | 6304 ArgumentListNode* Parser::ParseActualParameters( |
| 6282 ArgumentListNode* implicit_arguments, | 6305 ArgumentListNode* implicit_arguments, |
| 6283 bool require_const) { | 6306 bool require_const) { |
| 6284 TRACE_PARSER("ParseActualParameters"); | 6307 TRACE_PARSER("ParseActualParameters"); |
| 6285 ASSERT(CurrentToken() == Token::kLPAREN); | 6308 ASSERT(CurrentToken() == Token::kLPAREN); |
| 6286 const bool saved_mode = SetAllowFunctionLiterals(true); | 6309 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6287 ArgumentListNode* arguments; | 6310 ArgumentListNode* arguments; |
| 6288 if (implicit_arguments == NULL) { | 6311 if (implicit_arguments == NULL) { |
| 6289 arguments = new ArgumentListNode(token_index_); | 6312 arguments = new ArgumentListNode(TokenIndex()); |
| 6290 } else { | 6313 } else { |
| 6291 arguments = implicit_arguments; | 6314 arguments = implicit_arguments; |
| 6292 } | 6315 } |
| 6293 const GrowableObjectArray& names = | 6316 const GrowableObjectArray& names = |
| 6294 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 6317 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 6295 bool named_argument_seen = false; | 6318 bool named_argument_seen = false; |
| 6296 if (LookaheadToken(1) != Token::kRPAREN) { | 6319 if (LookaheadToken(1) != Token::kRPAREN) { |
| 6297 String& arg_name = String::Handle(); | 6320 String& arg_name = String::Handle(); |
| 6298 do { | 6321 do { |
| 6299 ASSERT((CurrentToken() == Token::kLPAREN) || | 6322 ASSERT((CurrentToken() == Token::kLPAREN) || |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 6328 arguments->set_names(Array::Handle(Array::MakeArray(names))); | 6351 arguments->set_names(Array::Handle(Array::MakeArray(names))); |
| 6329 } | 6352 } |
| 6330 return arguments; | 6353 return arguments; |
| 6331 } | 6354 } |
| 6332 | 6355 |
| 6333 | 6356 |
| 6334 AstNode* Parser::ParseStaticCall(const Class& cls, | 6357 AstNode* Parser::ParseStaticCall(const Class& cls, |
| 6335 const String& func_name, | 6358 const String& func_name, |
| 6336 intptr_t ident_pos) { | 6359 intptr_t ident_pos) { |
| 6337 TRACE_PARSER("ParseStaticCall"); | 6360 TRACE_PARSER("ParseStaticCall"); |
| 6338 const intptr_t call_pos = token_index_; | 6361 const intptr_t call_pos = TokenIndex(); |
| 6339 ASSERT(CurrentToken() == Token::kLPAREN); | 6362 ASSERT(CurrentToken() == Token::kLPAREN); |
| 6340 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6363 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 6341 const int num_arguments = arguments->length(); | 6364 const int num_arguments = arguments->length(); |
| 6342 const Function& func = Function::ZoneHandle( | 6365 const Function& func = Function::ZoneHandle( |
| 6343 Resolver::ResolveStatic(cls, | 6366 Resolver::ResolveStatic(cls, |
| 6344 func_name, | 6367 func_name, |
| 6345 num_arguments, | 6368 num_arguments, |
| 6346 arguments->names(), | 6369 arguments->names(), |
| 6347 Resolver::kIsQualified)); | 6370 Resolver::kIsQualified)); |
| 6348 if (func.IsNull()) { | 6371 if (func.IsNull()) { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 6378 // Could not resolve static method: throw an exception if the arguments | 6401 // Could not resolve static method: throw an exception if the arguments |
| 6379 // do not match or compile time error otherwise. | 6402 // do not match or compile time error otherwise. |
| 6380 const Function& test_func = Function::Handle( | 6403 const Function& test_func = Function::Handle( |
| 6381 Resolver::ResolveStaticByName(cls, func_name, Resolver::kIsQualified)); | 6404 Resolver::ResolveStaticByName(cls, func_name, Resolver::kIsQualified)); |
| 6382 if (test_func.IsNull()) { | 6405 if (test_func.IsNull()) { |
| 6383 ErrorMsg(ident_pos, "unresolved static method '%s'", | 6406 ErrorMsg(ident_pos, "unresolved static method '%s'", |
| 6384 func_name.ToCString()); | 6407 func_name.ToCString()); |
| 6385 } else { | 6408 } else { |
| 6386 ArgumentListNode* arguments = new ArgumentListNode(ident_pos); | 6409 ArgumentListNode* arguments = new ArgumentListNode(ident_pos); |
| 6387 arguments->Add(new LiteralNode( | 6410 arguments->Add(new LiteralNode( |
| 6388 token_index_, Integer::ZoneHandle(Integer::New(ident_pos)))); | 6411 TokenIndex(), Integer::ZoneHandle(Integer::New(ident_pos)))); |
| 6389 return MakeStaticCall(kStaticResolutionExceptionName, | 6412 return MakeStaticCall(kStaticResolutionExceptionName, |
| 6390 kThrowNewName, | 6413 kThrowNewName, |
| 6391 arguments); | 6414 arguments); |
| 6392 } | 6415 } |
| 6393 } | 6416 } |
| 6394 CheckFunctionIsCallable(call_pos, func); | 6417 CheckFunctionIsCallable(call_pos, func); |
| 6395 return new StaticCallNode(call_pos, func, arguments); | 6418 return new StaticCallNode(call_pos, func, arguments); |
| 6396 } | 6419 } |
| 6397 | 6420 |
| 6398 | 6421 |
| 6399 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 6422 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
| 6400 TRACE_PARSER("ParseInstanceCall"); | 6423 TRACE_PARSER("ParseInstanceCall"); |
| 6401 const intptr_t call_pos = token_index_; | 6424 const intptr_t call_pos = TokenIndex(); |
| 6402 if (CurrentToken() != Token::kLPAREN) { | 6425 if (CurrentToken() != Token::kLPAREN) { |
| 6403 ErrorMsg(call_pos, "left parenthesis expected"); | 6426 ErrorMsg(call_pos, "left parenthesis expected"); |
| 6404 } | 6427 } |
| 6405 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6428 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 6406 return new InstanceCallNode(call_pos, receiver, func_name, arguments); | 6429 return new InstanceCallNode(call_pos, receiver, func_name, arguments); |
| 6407 } | 6430 } |
| 6408 | 6431 |
| 6409 | 6432 |
| 6410 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 6433 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 6411 TRACE_PARSER("ParseClosureCall"); | 6434 TRACE_PARSER("ParseClosureCall"); |
| 6412 const intptr_t call_pos = token_index_; | 6435 const intptr_t call_pos = TokenIndex(); |
| 6413 ASSERT(CurrentToken() == Token::kLPAREN); | 6436 ASSERT(CurrentToken() == Token::kLPAREN); |
| 6414 EnsureExpressionTemp(); | 6437 EnsureExpressionTemp(); |
| 6415 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 6438 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 6416 return new ClosureCallNode(call_pos, closure, arguments); | 6439 return new ClosureCallNode(call_pos, closure, arguments); |
| 6417 } | 6440 } |
| 6418 | 6441 |
| 6419 | 6442 |
| 6420 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, | 6443 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, |
| 6421 const String& field_name) { | 6444 const String& field_name) { |
| 6422 TRACE_PARSER("ParseInstanceFieldAccess"); | 6445 TRACE_PARSER("ParseInstanceFieldAccess"); |
| 6423 AstNode* access = NULL; | 6446 AstNode* access = NULL; |
| 6424 const intptr_t call_pos = token_index_; | 6447 const intptr_t call_pos = TokenIndex(); |
| 6425 if (Token::IsAssignmentOperator(CurrentToken())) { | 6448 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 6426 Token::Kind assignment_op = CurrentToken(); | 6449 Token::Kind assignment_op = CurrentToken(); |
| 6427 ConsumeToken(); | 6450 ConsumeToken(); |
| 6428 AstNode* value = ParseExpr(kAllowConst); | 6451 AstNode* value = ParseExpr(kAllowConst); |
| 6429 AstNode* load_access = | 6452 AstNode* load_access = |
| 6430 new InstanceGetterNode(call_pos, receiver, field_name); | 6453 new InstanceGetterNode(call_pos, receiver, field_name); |
| 6431 AstNode* left_load_access = load_access; | 6454 AstNode* left_load_access = load_access; |
| 6432 if (assignment_op != Token::kASSIGN) { | 6455 if (assignment_op != Token::kASSIGN) { |
| 6433 // Compound assignment: store inputs with side effects into temp. locals. | 6456 // Compound assignment: store inputs with side effects into temp. locals. |
| 6434 left_load_access = PrepareCompoundAssignmentNodes(&load_access); | 6457 left_load_access = PrepareCompoundAssignmentNodes(&load_access); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 6461 // Access the field directly. | 6484 // Access the field directly. |
| 6462 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); | 6485 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); |
| 6463 } | 6486 } |
| 6464 | 6487 |
| 6465 | 6488 |
| 6466 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 6489 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| 6467 const String& field_name, | 6490 const String& field_name, |
| 6468 intptr_t ident_pos) { | 6491 intptr_t ident_pos) { |
| 6469 TRACE_PARSER("ParseStaticFieldAccess"); | 6492 TRACE_PARSER("ParseStaticFieldAccess"); |
| 6470 AstNode* access = NULL; | 6493 AstNode* access = NULL; |
| 6471 const intptr_t call_pos = token_index_; | 6494 const intptr_t call_pos = TokenIndex(); |
| 6472 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); | 6495 const Field& field = Field::ZoneHandle(cls.LookupStaticField(field_name)); |
| 6473 Function& func = Function::ZoneHandle(); | 6496 Function& func = Function::ZoneHandle(); |
| 6474 if (Token::IsAssignmentOperator(CurrentToken())) { | 6497 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 6475 Token::Kind assignment_op = CurrentToken(); | 6498 Token::Kind assignment_op = CurrentToken(); |
| 6476 if (field.IsNull()) { | 6499 if (field.IsNull()) { |
| 6477 // No field, check if we have an explicit setter function. | 6500 // No field, check if we have an explicit setter function. |
| 6478 const String& setter_name = | 6501 const String& setter_name = |
| 6479 String::ZoneHandle(Field::SetterName(field_name)); | 6502 String::ZoneHandle(Field::SetterName(field_name)); |
| 6480 const int kNumArguments = 1; // value. | 6503 const int kNumArguments = 1; // value. |
| 6481 const Array& kNoArgumentNames = Array::Handle(); | 6504 const Array& kNoArgumentNames = Array::Handle(); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 6507 } else { | 6530 } else { |
| 6508 // Field exists. | 6531 // Field exists. |
| 6509 if (field.is_final()) { | 6532 if (field.is_final()) { |
| 6510 // Field has been marked as final, report an error as the field | 6533 // Field has been marked as final, report an error as the field |
| 6511 // is not settable. | 6534 // is not settable. |
| 6512 ErrorMsg(ident_pos, | 6535 ErrorMsg(ident_pos, |
| 6513 "field '%s' is const static, cannot assign to it", | 6536 "field '%s' is const static, cannot assign to it", |
| 6514 field_name.ToCString()); | 6537 field_name.ToCString()); |
| 6515 return access; | 6538 return access; |
| 6516 } | 6539 } |
| 6517 load_access = GenerateStaticFieldLookup(field, token_index_); | 6540 load_access = GenerateStaticFieldLookup(field, TokenIndex()); |
| 6518 } | 6541 } |
| 6519 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); | 6542 value = ExpandAssignableOp(call_pos, assignment_op, load_access, value); |
| 6520 access = CreateAssignmentNode(load_access, value); | 6543 access = CreateAssignmentNode(load_access, value); |
| 6521 } else { // Not Token::IsAssignmentOperator(CurrentToken()). | 6544 } else { // Not Token::IsAssignmentOperator(CurrentToken()). |
| 6522 if (field.IsNull()) { | 6545 if (field.IsNull()) { |
| 6523 // No field, check if we have an explicit getter function. | 6546 // No field, check if we have an explicit getter function. |
| 6524 const String& getter_name = | 6547 const String& getter_name = |
| 6525 String::ZoneHandle(Field::GetterName(field_name)); | 6548 String::ZoneHandle(Field::GetterName(field_name)); |
| 6526 const int kNumArguments = 0; // no arguments. | 6549 const int kNumArguments = 0; // no arguments. |
| 6527 const Array& kNoArgumentNames = Array::Handle(); | 6550 const Array& kNoArgumentNames = Array::Handle(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 6541 return access; | 6564 return access; |
| 6542 } | 6565 } |
| 6543 access = CreateImplicitClosureNode(func, call_pos, NULL); | 6566 access = CreateImplicitClosureNode(func, call_pos, NULL); |
| 6544 } else { | 6567 } else { |
| 6545 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 6568 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); |
| 6546 access = new StaticGetterNode(call_pos, | 6569 access = new StaticGetterNode(call_pos, |
| 6547 Class::ZoneHandle(cls.raw()), | 6570 Class::ZoneHandle(cls.raw()), |
| 6548 field_name); | 6571 field_name); |
| 6549 } | 6572 } |
| 6550 } else { | 6573 } else { |
| 6551 return GenerateStaticFieldLookup(field, token_index_); | 6574 return GenerateStaticFieldLookup(field, TokenIndex()); |
| 6552 } | 6575 } |
| 6553 } | 6576 } |
| 6554 return access; | 6577 return access; |
| 6555 } | 6578 } |
| 6556 | 6579 |
| 6557 | 6580 |
| 6558 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 6581 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
| 6559 if (!node->IsPrimaryNode()) { | 6582 if (!node->IsPrimaryNode()) { |
| 6560 return node; | 6583 return node; |
| 6561 } | 6584 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6598 } | 6621 } |
| 6599 AstNode* receiver = LoadReceiver(primary->token_index()); | 6622 AstNode* receiver = LoadReceiver(primary->token_index()); |
| 6600 closure = CallGetter(primary->token_index(), receiver, funcname); | 6623 closure = CallGetter(primary->token_index(), receiver, funcname); |
| 6601 } | 6624 } |
| 6602 return closure; | 6625 return closure; |
| 6603 } | 6626 } |
| 6604 | 6627 |
| 6605 | 6628 |
| 6606 AstNode* Parser::ParsePostfixExpr() { | 6629 AstNode* Parser::ParsePostfixExpr() { |
| 6607 TRACE_PARSER("ParsePostfixExpr"); | 6630 TRACE_PARSER("ParsePostfixExpr"); |
| 6608 const intptr_t postfix_expr_pos = token_index_; | 6631 const intptr_t postfix_expr_pos = TokenIndex(); |
| 6609 AstNode* postfix_expr = ParsePrimary(); | 6632 AstNode* postfix_expr = ParsePrimary(); |
| 6610 while (true) { | 6633 while (true) { |
| 6611 AstNode* selector = NULL; | 6634 AstNode* selector = NULL; |
| 6612 AstNode* left = postfix_expr; | 6635 AstNode* left = postfix_expr; |
| 6613 if (CurrentToken() == Token::kPERIOD) { | 6636 if (CurrentToken() == Token::kPERIOD) { |
| 6614 ConsumeToken(); | 6637 ConsumeToken(); |
| 6615 if (left->IsPrimaryNode()) { | 6638 if (left->IsPrimaryNode()) { |
| 6616 if (left->AsPrimaryNode()->primary().IsFunction()) { | 6639 if (left->AsPrimaryNode()->primary().IsFunction()) { |
| 6617 left = LoadClosure(left->AsPrimaryNode()); | 6640 left = LoadClosure(left->AsPrimaryNode()); |
| 6618 } else { | 6641 } else { |
| 6619 left = LoadFieldIfUnresolved(left); | 6642 left = LoadFieldIfUnresolved(left); |
| 6620 } | 6643 } |
| 6621 } | 6644 } |
| 6622 const intptr_t ident_pos = token_index_; | 6645 const intptr_t ident_pos = TokenIndex(); |
| 6623 String* ident = ExpectIdentifier("identifier expected"); | 6646 String* ident = ExpectIdentifier("identifier expected"); |
| 6624 if (CurrentToken() == Token::kLPAREN) { | 6647 if (CurrentToken() == Token::kLPAREN) { |
| 6625 // Identifier followed by a opening paren: method call. | 6648 // Identifier followed by a opening paren: method call. |
| 6626 if (left->IsPrimaryNode() | 6649 if (left->IsPrimaryNode() |
| 6627 && left->AsPrimaryNode()->primary().IsClass()) { | 6650 && left->AsPrimaryNode()->primary().IsClass()) { |
| 6628 // Static method call prefixed with class name. | 6651 // Static method call prefixed with class name. |
| 6629 Class& cls = Class::CheckedHandle( | 6652 Class& cls = Class::CheckedHandle( |
| 6630 left->AsPrimaryNode()->primary().raw()); | 6653 left->AsPrimaryNode()->primary().raw()); |
| 6631 selector = ParseStaticCall(cls, *ident, ident_pos); | 6654 selector = ParseStaticCall(cls, *ident, ident_pos); |
| 6632 } else { | 6655 } else { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 6645 } | 6668 } |
| 6646 if (cls.IsNull()) { | 6669 if (cls.IsNull()) { |
| 6647 // Instance field access. | 6670 // Instance field access. |
| 6648 selector = ParseInstanceFieldAccess(left, *ident); | 6671 selector = ParseInstanceFieldAccess(left, *ident); |
| 6649 } else { | 6672 } else { |
| 6650 // Static field access. | 6673 // Static field access. |
| 6651 selector = ParseStaticFieldAccess(cls, *ident, ident_pos); | 6674 selector = ParseStaticFieldAccess(cls, *ident, ident_pos); |
| 6652 } | 6675 } |
| 6653 } | 6676 } |
| 6654 } else if (CurrentToken() == Token::kLBRACK) { | 6677 } else if (CurrentToken() == Token::kLBRACK) { |
| 6655 const intptr_t bracket_pos = token_index_; | 6678 const intptr_t bracket_pos = TokenIndex(); |
| 6656 ConsumeToken(); | 6679 ConsumeToken(); |
| 6657 left = LoadFieldIfUnresolved(left); | 6680 left = LoadFieldIfUnresolved(left); |
| 6658 const bool saved_mode = SetAllowFunctionLiterals(true); | 6681 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6659 AstNode* index = ParseExpr(kAllowConst); | 6682 AstNode* index = ParseExpr(kAllowConst); |
| 6660 SetAllowFunctionLiterals(saved_mode); | 6683 SetAllowFunctionLiterals(saved_mode); |
| 6661 ExpectToken(Token::kRBRACK); | 6684 ExpectToken(Token::kRBRACK); |
| 6662 AstNode* array = left; | 6685 AstNode* array = left; |
| 6663 if (left->IsPrimaryNode()) { | 6686 if (left->IsPrimaryNode()) { |
| 6664 PrimaryNode* primary = left->AsPrimaryNode(); | 6687 PrimaryNode* primary = left->AsPrimaryNode(); |
| 6665 if (primary->primary().IsFunction()) { | 6688 if (primary->primary().IsFunction()) { |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6913 // If the field is not initialized and not const, return the ast for the getter. | 6936 // If the field is not initialized and not const, return the ast for the getter. |
| 6914 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { | 6937 AstNode* Parser::RunStaticFieldInitializer(const Field& field) { |
| 6915 ASSERT(field.is_static()); | 6938 ASSERT(field.is_static()); |
| 6916 const Instance& value = Instance::Handle(field.value()); | 6939 const Instance& value = Instance::Handle(field.value()); |
| 6917 if (value.raw() == Object::transition_sentinel()) { | 6940 if (value.raw() == Object::transition_sentinel()) { |
| 6918 if (field.is_const()) { | 6941 if (field.is_const()) { |
| 6919 ErrorMsg("circular dependency while initializing static field '%s'", | 6942 ErrorMsg("circular dependency while initializing static field '%s'", |
| 6920 String::Handle(field.name()).ToCString()); | 6943 String::Handle(field.name()).ToCString()); |
| 6921 } else { | 6944 } else { |
| 6922 // The implicit static getter will throw the exception if necessary. | 6945 // The implicit static getter will throw the exception if necessary. |
| 6923 return new StaticGetterNode(token_index_, | 6946 return new StaticGetterNode(TokenIndex(), |
| 6924 Class::ZoneHandle(field.owner()), | 6947 Class::ZoneHandle(field.owner()), |
| 6925 String::ZoneHandle(field.name())); | 6948 String::ZoneHandle(field.name())); |
| 6926 } | 6949 } |
| 6927 } else if (value.raw() == Object::sentinel()) { | 6950 } else if (value.raw() == Object::sentinel()) { |
| 6928 // This field has not been referenced yet and thus the value has | 6951 // This field has not been referenced yet and thus the value has |
| 6929 // not been evaluated. If the field is const, call the static getter method | 6952 // not been evaluated. If the field is const, call the static getter method |
| 6930 // to evaluate the expression and canonicalize the value. | 6953 // to evaluate the expression and canonicalize the value. |
| 6931 if (field.is_const()) { | 6954 if (field.is_const()) { |
| 6932 field.set_value(Instance::Handle(Object::transition_sentinel())); | 6955 field.set_value(Instance::Handle(Object::transition_sentinel())); |
| 6933 const String& field_name = String::Handle(field.name()); | 6956 const String& field_name = String::Handle(field.name()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 6947 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 6970 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
| 6948 Object& const_value = Object::Handle( | 6971 Object& const_value = Object::Handle( |
| 6949 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); | 6972 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); |
| 6950 if (const_value.IsError()) { | 6973 if (const_value.IsError()) { |
| 6951 Error& error = Error::Handle(); | 6974 Error& error = Error::Handle(); |
| 6952 error ^= const_value.raw(); | 6975 error ^= const_value.raw(); |
| 6953 if (const_value.IsUnhandledException()) { | 6976 if (const_value.IsUnhandledException()) { |
| 6954 field.set_value(Instance::Handle()); | 6977 field.set_value(Instance::Handle()); |
| 6955 // It is a compile-time error if evaluation of a compile-time constant | 6978 // It is a compile-time error if evaluation of a compile-time constant |
| 6956 // would raise an exception. | 6979 // would raise an exception. |
| 6957 AppendErrorMsg(error, token_index_, | 6980 AppendErrorMsg(error, TokenIndex(), |
| 6958 "error initializing final field '%s'", | 6981 "error initializing final field '%s'", |
| 6959 String::Handle(field.name()).ToCString()); | 6982 String::Handle(field.name()).ToCString()); |
| 6960 } else { | 6983 } else { |
| 6961 Isolate::Current()->long_jump_base()->Jump(1, error); | 6984 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 6962 } | 6985 } |
| 6963 } | 6986 } |
| 6964 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 6987 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 6965 Instance& instance = Instance::Handle(); | 6988 Instance& instance = Instance::Handle(); |
| 6966 instance ^= const_value.raw(); | 6989 instance ^= const_value.raw(); |
| 6967 if (!instance.IsNull()) { | 6990 if (!instance.IsNull()) { |
| 6968 instance ^= instance.Canonicalize(); | 6991 instance ^= instance.Canonicalize(); |
| 6969 } | 6992 } |
| 6970 field.set_value(instance); | 6993 field.set_value(instance); |
| 6971 } else { | 6994 } else { |
| 6972 return new StaticGetterNode(token_index_, | 6995 return new StaticGetterNode(TokenIndex(), |
| 6973 Class::ZoneHandle(field.owner()), | 6996 Class::ZoneHandle(field.owner()), |
| 6974 String::ZoneHandle(field.name())); | 6997 String::ZoneHandle(field.name())); |
| 6975 } | 6998 } |
| 6976 } | 6999 } |
| 6977 return NULL; | 7000 return NULL; |
| 6978 } | 7001 } |
| 6979 | 7002 |
| 6980 | 7003 |
| 6981 RawObject* Parser::EvaluateConstConstructorCall( | 7004 RawObject* Parser::EvaluateConstConstructorCall( |
| 6982 const Class& type_class, | 7005 const Class& type_class, |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7400 // Parse "[" [ expr { "," expr } ["," ] "]". | 7423 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 7401 // Note: if the list literal is empty and the brackets have no whitespace | 7424 // Note: if the list literal is empty and the brackets have no whitespace |
| 7402 // between them, the scanner recognizes the opening and closing bracket | 7425 // between them, the scanner recognizes the opening and closing bracket |
| 7403 // as one token of type Token::kINDEX. | 7426 // as one token of type Token::kINDEX. |
| 7404 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 7427 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
| 7405 bool is_const, | 7428 bool is_const, |
| 7406 const AbstractTypeArguments& type_arguments) { | 7429 const AbstractTypeArguments& type_arguments) { |
| 7407 TRACE_PARSER("ParseListLiteral"); | 7430 TRACE_PARSER("ParseListLiteral"); |
| 7408 ASSERT(type_pos >= 0); | 7431 ASSERT(type_pos >= 0); |
| 7409 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 7432 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 7410 const intptr_t literal_pos = token_index_; | 7433 const intptr_t literal_pos = TokenIndex(); |
| 7411 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 7434 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 7412 ConsumeToken(); | 7435 ConsumeToken(); |
| 7413 | 7436 |
| 7414 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); | 7437 AbstractType& element_type = Type::ZoneHandle(Type::DynamicType()); |
| 7415 // If no type argument vector is provided, leave it as null, which is | 7438 // If no type argument vector is provided, leave it as null, which is |
| 7416 // equivalent to using Dynamic as the type argument for the element type. | 7439 // equivalent to using Dynamic as the type argument for the element type. |
| 7417 if (!type_arguments.IsNull()) { | 7440 if (!type_arguments.IsNull()) { |
| 7418 ASSERT(type_arguments.Length() > 0); | 7441 ASSERT(type_arguments.Length() > 0); |
| 7419 // List literals take a single type argument. | 7442 // List literals take a single type argument. |
| 7420 element_type = type_arguments.TypeAt(0); | 7443 element_type = type_arguments.TypeAt(0); |
| 7421 if (type_arguments.Length() != 1) { | 7444 if (type_arguments.Length() != 1) { |
| 7422 ErrorMsg(type_pos, | 7445 ErrorMsg(type_pos, |
| 7423 "a list literal takes one type argument specifying " | 7446 "a list literal takes one type argument specifying " |
| 7424 "the element type"); | 7447 "the element type"); |
| 7425 } | 7448 } |
| 7426 if (is_const && !element_type.IsInstantiated()) { | 7449 if (is_const && !element_type.IsInstantiated()) { |
| 7427 ErrorMsg(type_pos, | 7450 ErrorMsg(type_pos, |
| 7428 "the type argument of a constant list literal cannot include " | 7451 "the type argument of a constant list literal cannot include " |
| 7429 "a type variable"); | 7452 "a type variable"); |
| 7430 } | 7453 } |
| 7431 } | 7454 } |
| 7432 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); | 7455 ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1)); |
| 7433 | 7456 |
| 7434 // Parse the list elements. Note: there may be an optional extra | 7457 // Parse the list elements. Note: there may be an optional extra |
| 7435 // comma after the last element. | 7458 // comma after the last element. |
| 7436 ArrayNode* list = new ArrayNode(token_index_, type_arguments); | 7459 ArrayNode* list = new ArrayNode(TokenIndex(), type_arguments); |
| 7437 if (!is_empty_literal) { | 7460 if (!is_empty_literal) { |
| 7438 const bool saved_mode = SetAllowFunctionLiterals(true); | 7461 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7439 const String& dst_name = String::ZoneHandle( | 7462 const String& dst_name = String::ZoneHandle( |
| 7440 String::NewSymbol("list literal element")); | 7463 String::NewSymbol("list literal element")); |
| 7441 while (CurrentToken() != Token::kRBRACK) { | 7464 while (CurrentToken() != Token::kRBRACK) { |
| 7442 const intptr_t element_pos = token_index_; | 7465 const intptr_t element_pos = TokenIndex(); |
| 7443 AstNode* element = ParseExpr(is_const); | 7466 AstNode* element = ParseExpr(is_const); |
| 7444 if (FLAG_enable_type_checks && | 7467 if (FLAG_enable_type_checks && |
| 7445 !is_const && | 7468 !is_const && |
| 7446 !element_type.IsDynamicType()) { | 7469 !element_type.IsDynamicType()) { |
| 7447 element = new AssignableNode(element_pos, | 7470 element = new AssignableNode(element_pos, |
| 7448 element, | 7471 element, |
| 7449 element_type, | 7472 element_type, |
| 7450 dst_name); | 7473 dst_name); |
| 7451 } | 7474 } |
| 7452 list->AddElement(element); | 7475 list->AddElement(element); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7564 pairs->AddElement(value); | 7587 pairs->AddElement(value); |
| 7565 } | 7588 } |
| 7566 | 7589 |
| 7567 | 7590 |
| 7568 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 7591 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
| 7569 bool is_const, | 7592 bool is_const, |
| 7570 const AbstractTypeArguments& type_arguments) { | 7593 const AbstractTypeArguments& type_arguments) { |
| 7571 TRACE_PARSER("ParseMapLiteral"); | 7594 TRACE_PARSER("ParseMapLiteral"); |
| 7572 ASSERT(type_pos >= 0); | 7595 ASSERT(type_pos >= 0); |
| 7573 ASSERT(CurrentToken() == Token::kLBRACE); | 7596 ASSERT(CurrentToken() == Token::kLBRACE); |
| 7574 const intptr_t literal_pos = token_index_; | 7597 const intptr_t literal_pos = TokenIndex(); |
| 7575 ConsumeToken(); | 7598 ConsumeToken(); |
| 7576 | 7599 |
| 7577 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); | 7600 AbstractType& value_type = Type::ZoneHandle(Type::DynamicType()); |
| 7578 AbstractTypeArguments& map_type_arguments = | 7601 AbstractTypeArguments& map_type_arguments = |
| 7579 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); | 7602 AbstractTypeArguments::ZoneHandle(type_arguments.raw()); |
| 7580 // If no type argument vector is provided, leave it as null, which is | 7603 // If no type argument vector is provided, leave it as null, which is |
| 7581 // equivalent to using Dynamic as the type argument for the value type. | 7604 // equivalent to using Dynamic as the type argument for the value type. |
| 7582 if (!map_type_arguments.IsNull()) { | 7605 if (!map_type_arguments.IsNull()) { |
| 7583 ASSERT(map_type_arguments.Length() > 0); | 7606 ASSERT(map_type_arguments.Length() > 0); |
| 7584 // Map literals take a single type argument. | 7607 // Map literals take a single type argument. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 7612 } | 7635 } |
| 7613 } | 7636 } |
| 7614 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 7637 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 7615 map_type_arguments ^= map_type_arguments.Canonicalize(); | 7638 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 7616 | 7639 |
| 7617 // Parse the map entries. Note: there may be an optional extra | 7640 // Parse the map entries. Note: there may be an optional extra |
| 7618 // comma after the last entry. | 7641 // comma after the last entry. |
| 7619 // The kv_pair array is temporary and of element type Dynamic. It is passed | 7642 // The kv_pair array is temporary and of element type Dynamic. It is passed |
| 7620 // to the factory to initialize a properly typed map. | 7643 // to the factory to initialize a properly typed map. |
| 7621 ArrayNode* kv_pairs = | 7644 ArrayNode* kv_pairs = |
| 7622 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 7645 new ArrayNode(TokenIndex(), TypeArguments::ZoneHandle()); |
| 7623 const String& dst_name = String::ZoneHandle( | 7646 const String& dst_name = String::ZoneHandle( |
| 7624 String::NewSymbol("list literal element")); | 7647 String::NewSymbol("list literal element")); |
| 7625 while (CurrentToken() != Token::kRBRACE) { | 7648 while (CurrentToken() != Token::kRBRACE) { |
| 7626 AstNode* key = NULL; | 7649 AstNode* key = NULL; |
| 7627 if (CurrentToken() == Token::kSTRING) { | 7650 if (CurrentToken() == Token::kSTRING) { |
| 7628 key = ParseStringLiteral(); | 7651 key = ParseStringLiteral(); |
| 7629 } | 7652 } |
| 7630 if (key == NULL) { | 7653 if (key == NULL) { |
| 7631 ErrorMsg("map entry key must be string literal"); | 7654 ErrorMsg("map entry key must be string literal"); |
| 7632 } else if (is_const && !key->IsLiteralNode()) { | 7655 } else if (is_const && !key->IsLiteralNode()) { |
| 7633 ErrorMsg("map entry key must be compile time constant string"); | 7656 ErrorMsg("map entry key must be compile time constant string"); |
| 7634 } | 7657 } |
| 7635 ExpectToken(Token::kCOLON); | 7658 ExpectToken(Token::kCOLON); |
| 7636 const bool saved_mode = SetAllowFunctionLiterals(true); | 7659 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7637 const intptr_t value_pos = token_index_; | 7660 const intptr_t value_pos = TokenIndex(); |
| 7638 AstNode* value = ParseExpr(is_const); | 7661 AstNode* value = ParseExpr(is_const); |
| 7639 SetAllowFunctionLiterals(saved_mode); | 7662 SetAllowFunctionLiterals(saved_mode); |
| 7640 if (FLAG_enable_type_checks && | 7663 if (FLAG_enable_type_checks && |
| 7641 !is_const && | 7664 !is_const && |
| 7642 !value_type.IsDynamicType()) { | 7665 !value_type.IsDynamicType()) { |
| 7643 value = new AssignableNode(value_pos, | 7666 value = new AssignableNode(value_pos, |
| 7644 value, | 7667 value, |
| 7645 value_type, | 7668 value_type, |
| 7646 dst_name); | 7669 dst_name); |
| 7647 } | 7670 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7690 } | 7713 } |
| 7691 key_value_array ^= key_value_array.Canonicalize(); | 7714 key_value_array ^= key_value_array.Canonicalize(); |
| 7692 key_value_array.MakeImmutable(); | 7715 key_value_array.MakeImmutable(); |
| 7693 | 7716 |
| 7694 // Construct the map object. | 7717 // Construct the map object. |
| 7695 const String& immutable_map_class_name = | 7718 const String& immutable_map_class_name = |
| 7696 String::Handle(String::NewSymbol(kImmutableMapName)); | 7719 String::Handle(String::NewSymbol(kImmutableMapName)); |
| 7697 const Class& immutable_map_class = | 7720 const Class& immutable_map_class = |
| 7698 Class::Handle(LookupImplClass(immutable_map_class_name)); | 7721 Class::Handle(LookupImplClass(immutable_map_class_name)); |
| 7699 ASSERT(!immutable_map_class.IsNull()); | 7722 ASSERT(!immutable_map_class.IsNull()); |
| 7700 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); | 7723 ArgumentListNode* constr_args = new ArgumentListNode(TokenIndex()); |
| 7701 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); | 7724 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); |
| 7702 const String& constr_name = | 7725 const String& constr_name = |
| 7703 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); | 7726 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); |
| 7704 const Function& map_constr = Function::ZoneHandle( | 7727 const Function& map_constr = Function::ZoneHandle( |
| 7705 immutable_map_class.LookupConstructor(constr_name)); | 7728 immutable_map_class.LookupConstructor(constr_name)); |
| 7706 ASSERT(!map_constr.IsNull()); | 7729 ASSERT(!map_constr.IsNull()); |
| 7707 const Object& constructor_result = Object::Handle( | 7730 const Object& constructor_result = Object::Handle( |
| 7708 EvaluateConstConstructorCall(immutable_map_class, | 7731 EvaluateConstConstructorCall(immutable_map_class, |
| 7709 map_type_arguments, | 7732 map_type_arguments, |
| 7710 map_constr, | 7733 map_constr, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7744 } | 7767 } |
| 7745 | 7768 |
| 7746 | 7769 |
| 7747 AstNode* Parser::ParseCompoundLiteral() { | 7770 AstNode* Parser::ParseCompoundLiteral() { |
| 7748 TRACE_PARSER("ParseCompoundLiteral"); | 7771 TRACE_PARSER("ParseCompoundLiteral"); |
| 7749 bool is_const = false; | 7772 bool is_const = false; |
| 7750 if (CurrentToken() == Token::kCONST) { | 7773 if (CurrentToken() == Token::kCONST) { |
| 7751 is_const = true; | 7774 is_const = true; |
| 7752 ConsumeToken(); | 7775 ConsumeToken(); |
| 7753 } | 7776 } |
| 7754 const intptr_t type_pos = token_index_; | 7777 const intptr_t type_pos = TokenIndex(); |
| 7755 Error& malformed_error = Error::Handle(); | 7778 Error& malformed_error = Error::Handle(); |
| 7756 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( | 7779 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle( |
| 7757 ParseTypeArguments(&malformed_error, | 7780 ParseTypeArguments(&malformed_error, |
| 7758 ClassFinalizer::kFinalizeWellFormed)); | 7781 ClassFinalizer::kFinalizeWellFormed)); |
| 7759 // Map and List interfaces do not declare bounds on their type parameters, so | 7782 // Map and List interfaces do not declare bounds on their type parameters, so |
| 7760 // we should never see a malformed type error here. | 7783 // we should never see a malformed type error here. |
| 7761 // Note that a bound error is the only possible malformed type error returned | 7784 // Note that a bound error is the only possible malformed type error returned |
| 7762 // when requesting kFinalizeWellFormed type finalization. | 7785 // when requesting kFinalizeWellFormed type finalization. |
| 7763 ASSERT(malformed_error.IsNull()); | 7786 ASSERT(malformed_error.IsNull()); |
| 7764 AstNode* primary = NULL; | 7787 AstNode* primary = NULL; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 7785 String::Handle(String::Concat(type_class_name, period)); | 7808 String::Handle(String::Concat(type_class_name, period)); |
| 7786 if (named_constructor != NULL) { | 7809 if (named_constructor != NULL) { |
| 7787 constructor_name = String::Concat(constructor_name, *named_constructor); | 7810 constructor_name = String::Concat(constructor_name, *named_constructor); |
| 7788 } | 7811 } |
| 7789 return constructor_name; | 7812 return constructor_name; |
| 7790 } | 7813 } |
| 7791 | 7814 |
| 7792 | 7815 |
| 7793 AstNode* Parser::ParseNewOperator() { | 7816 AstNode* Parser::ParseNewOperator() { |
| 7794 TRACE_PARSER("ParseNewOperator"); | 7817 TRACE_PARSER("ParseNewOperator"); |
| 7795 const intptr_t new_pos = token_index_; | 7818 const intptr_t new_pos = TokenIndex(); |
| 7796 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7819 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7797 bool is_const = (CurrentToken() == Token::kCONST); | 7820 bool is_const = (CurrentToken() == Token::kCONST); |
| 7798 ConsumeToken(); | 7821 ConsumeToken(); |
| 7799 if (!IsIdentifier()) { | 7822 if (!IsIdentifier()) { |
| 7800 ErrorMsg("type name expected"); | 7823 ErrorMsg("type name expected"); |
| 7801 } | 7824 } |
| 7802 intptr_t type_pos = token_index_; | 7825 intptr_t type_pos = TokenIndex(); |
| 7803 const AbstractType& type = AbstractType::Handle( | 7826 const AbstractType& type = AbstractType::Handle( |
| 7804 ParseType(ClassFinalizer::kFinalizeWellFormed)); | 7827 ParseType(ClassFinalizer::kFinalizeWellFormed)); |
| 7805 // Malformed bounds never result in a compile time error, therefore, the | 7828 // Malformed bounds never result in a compile time error, therefore, the |
| 7806 // parsed type may be malformed although we requested kFinalizeWellFormed. | 7829 // parsed type may be malformed although we requested kFinalizeWellFormed. |
| 7807 // In that case, we throw a dynamic type error instead of calling the | 7830 // In that case, we throw a dynamic type error instead of calling the |
| 7808 // constructor. | 7831 // constructor. |
| 7809 if (type.IsTypeParameter()) { | 7832 if (type.IsTypeParameter()) { |
| 7810 ErrorMsg(type_pos, | 7833 ErrorMsg(type_pos, |
| 7811 "type parameter '%s' cannot be instantiated", | 7834 "type parameter '%s' cannot be instantiated", |
| 7812 String::Handle(type.Name()).ToCString()); | 7835 String::Handle(type.Name()).ToCString()); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 7832 String* named_constructor = NULL; | 7855 String* named_constructor = NULL; |
| 7833 if (CurrentToken() == Token::kPERIOD) { | 7856 if (CurrentToken() == Token::kPERIOD) { |
| 7834 ConsumeToken(); | 7857 ConsumeToken(); |
| 7835 named_constructor = ExpectIdentifier("name of constructor expected"); | 7858 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 7836 } | 7859 } |
| 7837 | 7860 |
| 7838 // Parse constructor parameters. | 7861 // Parse constructor parameters. |
| 7839 if (CurrentToken() != Token::kLPAREN) { | 7862 if (CurrentToken() != Token::kLPAREN) { |
| 7840 ErrorMsg("'(' expected"); | 7863 ErrorMsg("'(' expected"); |
| 7841 } | 7864 } |
| 7842 intptr_t call_pos = token_index_; | 7865 intptr_t call_pos = TokenIndex(); |
| 7843 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 7866 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 7844 | 7867 |
| 7845 // A constructor has an implicit 'this' parameter (instance to construct) | 7868 // A constructor has an implicit 'this' parameter (instance to construct) |
| 7846 // and a factory has an implicit 'this' parameter (type_arguments). | 7869 // and a factory has an implicit 'this' parameter (type_arguments). |
| 7847 // A constructor has a second implicit 'phase' parameter. | 7870 // A constructor has a second implicit 'phase' parameter. |
| 7848 intptr_t arguments_length = arguments->length() + 2; | 7871 intptr_t arguments_length = arguments->length() + 2; |
| 7849 | 7872 |
| 7850 if (type_class.is_interface()) { | 7873 if (type_class.is_interface()) { |
| 7851 // We need to make sure that an appropriate constructor is | 7874 // We need to make sure that an appropriate constructor is |
| 7852 // declared in the interface. | 7875 // declared in the interface. |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8054 | 8077 |
| 8055 // A string literal consists of the concatenation of the next n tokens | 8078 // A string literal consists of the concatenation of the next n tokens |
| 8056 // that satisfy the EBNF grammar: | 8079 // that satisfy the EBNF grammar: |
| 8057 // literal = kSTRING {{ interpol } kSTRING } | 8080 // literal = kSTRING {{ interpol } kSTRING } |
| 8058 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 8081 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 8059 // In other words, the scanner breaks down interpolated strings so that | 8082 // In other words, the scanner breaks down interpolated strings so that |
| 8060 // a string literal always begins and ends with a kSTRING token. | 8083 // a string literal always begins and ends with a kSTRING token. |
| 8061 AstNode* Parser::ParseStringLiteral() { | 8084 AstNode* Parser::ParseStringLiteral() { |
| 8062 TRACE_PARSER("ParseStringLiteral"); | 8085 TRACE_PARSER("ParseStringLiteral"); |
| 8063 AstNode* primary = NULL; | 8086 AstNode* primary = NULL; |
| 8064 const intptr_t literal_start = token_index_; | 8087 const intptr_t literal_start = TokenIndex(); |
| 8065 ASSERT(CurrentToken() == Token::kSTRING); | 8088 ASSERT(CurrentToken() == Token::kSTRING); |
| 8066 Token::Kind l1_token = LookaheadToken(1); | 8089 Token::Kind l1_token = LookaheadToken(1); |
| 8067 if ((l1_token != Token::kSTRING) && | 8090 if ((l1_token != Token::kSTRING) && |
| 8068 (l1_token != Token::kINTERPOL_VAR) && | 8091 (l1_token != Token::kINTERPOL_VAR) && |
| 8069 (l1_token != Token::kINTERPOL_START)) { | 8092 (l1_token != Token::kINTERPOL_START)) { |
| 8070 // Common case: no interpolation. | 8093 // Common case: no interpolation. |
| 8071 primary = new LiteralNode(literal_start, *CurrentLiteral()); | 8094 primary = new LiteralNode(literal_start, *CurrentLiteral()); |
| 8072 ConsumeToken(); | 8095 ConsumeToken(); |
| 8073 return primary; | 8096 return primary; |
| 8074 } | 8097 } |
| 8075 // String interpolation needed. | 8098 // String interpolation needed. |
| 8076 bool is_compiletime_const = true; | 8099 bool is_compiletime_const = true; |
| 8077 ArrayNode* values = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 8100 ArrayNode* values = new ArrayNode(TokenIndex(), TypeArguments::ZoneHandle()); |
| 8078 while (CurrentToken() == Token::kSTRING) { | 8101 while (CurrentToken() == Token::kSTRING) { |
| 8079 values->AddElement(new LiteralNode(token_index_, *CurrentLiteral())); | 8102 values->AddElement(new LiteralNode(TokenIndex(), *CurrentLiteral())); |
| 8080 ConsumeToken(); | 8103 ConsumeToken(); |
| 8081 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 8104 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 8082 (CurrentToken() == Token::kINTERPOL_START)) { | 8105 (CurrentToken() == Token::kINTERPOL_START)) { |
| 8083 AstNode* expr = NULL; | 8106 AstNode* expr = NULL; |
| 8084 const intptr_t expr_pos = token_index_; | 8107 const intptr_t expr_pos = TokenIndex(); |
| 8085 if (CurrentToken() == Token::kINTERPOL_VAR) { | 8108 if (CurrentToken() == Token::kINTERPOL_VAR) { |
| 8086 expr = ResolveVarOrField(token_index_, *CurrentLiteral()); | 8109 expr = ResolveVarOrField(TokenIndex(), *CurrentLiteral()); |
| 8087 ASSERT(!expr->IsPrimaryNode()); | 8110 ASSERT(!expr->IsPrimaryNode()); |
| 8088 ConsumeToken(); | 8111 ConsumeToken(); |
| 8089 } else { | 8112 } else { |
| 8090 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 8113 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
| 8091 ConsumeToken(); | 8114 ConsumeToken(); |
| 8092 expr = ParseExpr(kAllowConst); | 8115 expr = ParseExpr(kAllowConst); |
| 8093 ExpectToken(Token::kINTERPOL_END); | 8116 ExpectToken(Token::kINTERPOL_END); |
| 8094 } | 8117 } |
| 8095 // Check if this interpolated string is still considered a compile time | 8118 // Check if this interpolated string is still considered a compile time |
| 8096 // constant. If it is we need to evaluate if the current string part is | 8119 // constant. If it is we need to evaluate if the current string part is |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8146 ConsumeToken(); | 8169 ConsumeToken(); |
| 8147 if ((CurrentToken() != Token::kINTERPOL_VAR) && | 8170 if ((CurrentToken() != Token::kINTERPOL_VAR) && |
| 8148 (CurrentToken() != Token::kINTERPOL_START)) { | 8171 (CurrentToken() != Token::kINTERPOL_START)) { |
| 8149 break; | 8172 break; |
| 8150 } | 8173 } |
| 8151 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 8174 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 8152 (CurrentToken() == Token::kINTERPOL_START)) { | 8175 (CurrentToken() == Token::kINTERPOL_START)) { |
| 8153 if (CurrentToken() == Token::kINTERPOL_START) { | 8176 if (CurrentToken() == Token::kINTERPOL_START) { |
| 8154 ConsumeToken(); | 8177 ConsumeToken(); |
| 8155 if (IsIdentifier()) { | 8178 if (IsIdentifier()) { |
| 8156 resolved_name = ResolveImportVar(token_index_, *CurrentLiteral()); | 8179 resolved_name = ResolveImportVar(TokenIndex(), *CurrentLiteral()); |
| 8157 result = String::Concat(result, resolved_name); | 8180 result = String::Concat(result, resolved_name); |
| 8158 ConsumeToken(); | 8181 ConsumeToken(); |
| 8159 if (CurrentToken() != Token::kINTERPOL_END) { | 8182 if (CurrentToken() != Token::kINTERPOL_END) { |
| 8160 ErrorMsg("'}' expected"); | 8183 ErrorMsg("'}' expected"); |
| 8161 } | 8184 } |
| 8162 ConsumeToken(); | 8185 ConsumeToken(); |
| 8163 } else { | 8186 } else { |
| 8164 ErrorMsg("identifier expected"); | 8187 ErrorMsg("identifier expected"); |
| 8165 } | 8188 } |
| 8166 } else { | 8189 } else { |
| 8167 ASSERT(CurrentToken() == Token::kINTERPOL_VAR); | 8190 ASSERT(CurrentToken() == Token::kINTERPOL_VAR); |
| 8168 resolved_name = ResolveImportVar(token_index_, *CurrentLiteral()); | 8191 resolved_name = ResolveImportVar(TokenIndex(), *CurrentLiteral()); |
| 8169 result = String::Concat(result, resolved_name); | 8192 result = String::Concat(result, resolved_name); |
| 8170 ConsumeToken(); | 8193 ConsumeToken(); |
| 8171 } | 8194 } |
| 8172 } | 8195 } |
| 8173 // A string literal always ends with a kSTRING token. | 8196 // A string literal always ends with a kSTRING token. |
| 8174 ASSERT(CurrentToken() == Token::kSTRING); | 8197 ASSERT(CurrentToken() == Token::kSTRING); |
| 8175 } | 8198 } |
| 8176 return &result; | 8199 return &result; |
| 8177 } | 8200 } |
| 8178 | 8201 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 8193 if (qual_ident.lib_prefix == NULL) { | 8216 if (qual_ident.lib_prefix == NULL) { |
| 8194 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, | 8217 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 8195 *qual_ident.ident, | 8218 *qual_ident.ident, |
| 8196 &primary)) { | 8219 &primary)) { |
| 8197 // Check whether the identifier is a type parameter. Type parameters | 8220 // Check whether the identifier is a type parameter. Type parameters |
| 8198 // can never be used as part of primary expressions. | 8221 // can never be used as part of primary expressions. |
| 8199 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 8222 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 8200 if (!scope_class.IsNull()) { | 8223 if (!scope_class.IsNull()) { |
| 8201 TypeParameter& type_param = TypeParameter::ZoneHandle( | 8224 TypeParameter& type_param = TypeParameter::ZoneHandle( |
| 8202 scope_class.LookupTypeParameter(*(qual_ident.ident), | 8225 scope_class.LookupTypeParameter(*(qual_ident.ident), |
| 8203 token_index_)); | 8226 TokenIndex())); |
| 8204 if (!type_param.IsNull()) { | 8227 if (!type_param.IsNull()) { |
| 8205 String& type_param_name = String::Handle(type_param.Name()); | 8228 String& type_param_name = String::Handle(type_param.Name()); |
| 8206 ErrorMsg(qual_ident.ident_pos, | 8229 ErrorMsg(qual_ident.ident_pos, |
| 8207 "illegal use of type parameter %s", | 8230 "illegal use of type parameter %s", |
| 8208 type_param_name.ToCString()); | 8231 type_param_name.ToCString()); |
| 8209 } | 8232 } |
| 8210 } | 8233 } |
| 8211 // This is a non-local unqualified identifier so resolve the | 8234 // This is a non-local unqualified identifier so resolve the |
| 8212 // identifier locally in the main app library and all libraries | 8235 // identifier locally in the main app library and all libraries |
| 8213 // imported by it. | 8236 // imported by it. |
| 8214 primary = ResolveIdentInLibraryScope(library_, | 8237 primary = ResolveIdentInLibraryScope(library_, |
| 8215 qual_ident, | 8238 qual_ident, |
| 8216 kResolveIncludingImports); | 8239 kResolveIncludingImports); |
| 8217 } | 8240 } |
| 8218 } else { | 8241 } else { |
| 8219 // This is a qualified identifier with a library prefix so resolve | 8242 // This is a qualified identifier with a library prefix so resolve |
| 8220 // the identifier locally in that library (we do not include the | 8243 // the identifier locally in that library (we do not include the |
| 8221 // libraries imported by that library). | 8244 // libraries imported by that library). |
| 8222 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), | 8245 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), |
| 8223 qual_ident); | 8246 qual_ident); |
| 8224 } | 8247 } |
| 8225 ASSERT(primary != NULL); | 8248 ASSERT(primary != NULL); |
| 8226 } else if (CurrentToken() == Token::kTHIS) { | 8249 } else if (CurrentToken() == Token::kTHIS) { |
| 8227 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 8250 const String& this_name = String::Handle(String::NewSymbol(kThisName)); |
| 8228 LocalVariable* local = LookupLocalScope(this_name); | 8251 LocalVariable* local = LookupLocalScope(this_name); |
| 8229 if (local == NULL) { | 8252 if (local == NULL) { |
| 8230 ErrorMsg("receiver 'this' is not in scope"); | 8253 ErrorMsg("receiver 'this' is not in scope"); |
| 8231 } | 8254 } |
| 8232 primary = new LoadLocalNode(token_index_, *local); | 8255 primary = new LoadLocalNode(TokenIndex(), *local); |
| 8233 ConsumeToken(); | 8256 ConsumeToken(); |
| 8234 } else if (CurrentToken() == Token::kINTEGER) { | 8257 } else if (CurrentToken() == Token::kINTEGER) { |
| 8235 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); | 8258 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); |
| 8236 primary = new LiteralNode(token_index_, literal); | 8259 primary = new LiteralNode(TokenIndex(), literal); |
| 8237 ConsumeToken(); | 8260 ConsumeToken(); |
| 8238 } else if (CurrentToken() == Token::kTRUE) { | 8261 } else if (CurrentToken() == Token::kTRUE) { |
| 8239 primary = new LiteralNode(token_index_, Bool::ZoneHandle(Bool::True())); | 8262 primary = new LiteralNode(TokenIndex(), Bool::ZoneHandle(Bool::True())); |
| 8240 ConsumeToken(); | 8263 ConsumeToken(); |
| 8241 } else if (CurrentToken() == Token::kFALSE) { | 8264 } else if (CurrentToken() == Token::kFALSE) { |
| 8242 primary = new LiteralNode(token_index_, Bool::ZoneHandle(Bool::False())); | 8265 primary = new LiteralNode(TokenIndex(), Bool::ZoneHandle(Bool::False())); |
| 8243 ConsumeToken(); | 8266 ConsumeToken(); |
| 8244 } else if (CurrentToken() == Token::kNULL) { | 8267 } else if (CurrentToken() == Token::kNULL) { |
| 8245 primary = new LiteralNode(token_index_, Instance::ZoneHandle()); | 8268 primary = new LiteralNode(TokenIndex(), Instance::ZoneHandle()); |
| 8246 ConsumeToken(); | 8269 ConsumeToken(); |
| 8247 } else if (CurrentToken() == Token::kLPAREN) { | 8270 } else if (CurrentToken() == Token::kLPAREN) { |
| 8248 ConsumeToken(); | 8271 ConsumeToken(); |
| 8249 const bool saved_mode = SetAllowFunctionLiterals(true); | 8272 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 8250 primary = ParseExpr(kAllowConst); | 8273 primary = ParseExpr(kAllowConst); |
| 8251 SetAllowFunctionLiterals(saved_mode); | 8274 SetAllowFunctionLiterals(saved_mode); |
| 8252 ExpectToken(Token::kRPAREN); | 8275 ExpectToken(Token::kRPAREN); |
| 8253 } else if (CurrentToken() == Token::kDOUBLE) { | 8276 } else if (CurrentToken() == Token::kDOUBLE) { |
| 8254 Double& double_value = Double::ZoneHandle(CurrentDoubleLiteral()); | 8277 Double& double_value = Double::ZoneHandle(CurrentDoubleLiteral()); |
| 8255 if (double_value.IsNull()) { | 8278 if (double_value.IsNull()) { |
| 8256 ErrorMsg("invalid double literal"); | 8279 ErrorMsg("invalid double literal"); |
| 8257 } | 8280 } |
| 8258 primary = new LiteralNode(token_index_, double_value); | 8281 primary = new LiteralNode(TokenIndex(), double_value); |
| 8259 ConsumeToken(); | 8282 ConsumeToken(); |
| 8260 } else if (CurrentToken() == Token::kSTRING) { | 8283 } else if (CurrentToken() == Token::kSTRING) { |
| 8261 primary = ParseStringLiteral(); | 8284 primary = ParseStringLiteral(); |
| 8262 } else if (CurrentToken() == Token::kNEW) { | 8285 } else if (CurrentToken() == Token::kNEW) { |
| 8263 primary = ParseNewOperator(); | 8286 primary = ParseNewOperator(); |
| 8264 } else if (CurrentToken() == Token::kCONST) { | 8287 } else if (CurrentToken() == Token::kCONST) { |
| 8265 if ((LookaheadToken(1) == Token::kLT) || | 8288 if ((LookaheadToken(1) == Token::kLT) || |
| 8266 (LookaheadToken(1) == Token::kLBRACK) || | 8289 (LookaheadToken(1) == Token::kLBRACK) || |
| 8267 (LookaheadToken(1) == Token::kINDEX) || | 8290 (LookaheadToken(1) == Token::kINDEX) || |
| 8268 (LookaheadToken(1) == Token::kLBRACE)) { | 8291 (LookaheadToken(1) == Token::kLBRACE)) { |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8580 void Parser::SkipQualIdent() { | 8603 void Parser::SkipQualIdent() { |
| 8581 ASSERT(IsIdentifier()); | 8604 ASSERT(IsIdentifier()); |
| 8582 ConsumeToken(); | 8605 ConsumeToken(); |
| 8583 if (CurrentToken() == Token::kPERIOD) { | 8606 if (CurrentToken() == Token::kPERIOD) { |
| 8584 ConsumeToken(); // Consume the kPERIOD token. | 8607 ConsumeToken(); // Consume the kPERIOD token. |
| 8585 ExpectIdentifier("identifier expected after '.'"); | 8608 ExpectIdentifier("identifier expected after '.'"); |
| 8586 } | 8609 } |
| 8587 } | 8610 } |
| 8588 | 8611 |
| 8589 } // namespace dart | 8612 } // namespace dart |
| OLD | NEW |