| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 5392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5403 | 5403 |
| 5404 // Returns ast nodes of the variable initialization. | 5404 // Returns ast nodes of the variable initialization. |
| 5405 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 5405 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 5406 bool is_final, | 5406 bool is_final, |
| 5407 bool is_const) { | 5407 bool is_const) { |
| 5408 TRACE_PARSER("ParseVariableDeclaration"); | 5408 TRACE_PARSER("ParseVariableDeclaration"); |
| 5409 ASSERT(IsIdentifier()); | 5409 ASSERT(IsIdentifier()); |
| 5410 const intptr_t ident_pos = TokenPos(); | 5410 const intptr_t ident_pos = TokenPos(); |
| 5411 const String& ident = *CurrentLiteral(); | 5411 const String& ident = *CurrentLiteral(); |
| 5412 LocalVariable* variable = new LocalVariable(ident_pos, ident, type); | 5412 LocalVariable* variable = new LocalVariable(ident_pos, ident, type); |
| 5413 ASSERT(current_block_ != NULL); | |
| 5414 ASSERT(current_block_->scope != NULL); | |
| 5415 const intptr_t previous_pos = | |
| 5416 current_block_->scope->PreviousReferencePos(ident); | |
| 5417 if (previous_pos >= 0) { | |
| 5418 ASSERT(!script_.IsNull()); | |
| 5419 intptr_t line_number; | |
| 5420 script_.GetTokenLocation(previous_pos, &line_number, NULL); | |
| 5421 ErrorMsg(ident_pos, | |
| 5422 "identifier '%s' previously used in line %" Pd "", | |
| 5423 ident.ToCString(), | |
| 5424 line_number); | |
| 5425 } | |
| 5426 ConsumeToken(); // Variable identifier. | 5413 ConsumeToken(); // Variable identifier. |
| 5427 AstNode* initialization = NULL; | 5414 AstNode* initialization = NULL; |
| 5428 if (CurrentToken() == Token::kASSIGN) { | 5415 if (CurrentToken() == Token::kASSIGN) { |
| 5429 // Variable initialization. | 5416 // Variable initialization. |
| 5430 const intptr_t assign_pos = TokenPos(); | 5417 const intptr_t assign_pos = TokenPos(); |
| 5431 ConsumeToken(); | 5418 ConsumeToken(); |
| 5432 AstNode* expr = ParseExpr(is_const, kConsumeCascades); | 5419 AstNode* expr = ParseExpr(is_const, kConsumeCascades); |
| 5433 initialization = new StoreLocalNode(assign_pos, variable, expr); | 5420 initialization = new StoreLocalNode(assign_pos, variable, expr); |
| 5434 if (is_const) { | 5421 if (is_const) { |
| 5435 ASSERT(expr->IsLiteralNode()); | 5422 ASSERT(expr->IsLiteralNode()); |
| 5436 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 5423 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 5437 } | 5424 } |
| 5438 } else if (is_final || is_const) { | 5425 } else if (is_final || is_const) { |
| 5439 ErrorMsg(ident_pos, | 5426 ErrorMsg(ident_pos, |
| 5440 "missing initialization of 'final' or 'const' variable"); | 5427 "missing initialization of 'final' or 'const' variable"); |
| 5441 } else { | 5428 } else { |
| 5442 // Initialize variable with null. | 5429 // Initialize variable with null. |
| 5443 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); | 5430 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); |
| 5444 initialization = new StoreLocalNode(ident_pos, variable, null_expr); | 5431 initialization = new StoreLocalNode(ident_pos, variable, null_expr); |
| 5445 } | 5432 } |
| 5433 |
| 5434 ASSERT(current_block_ != NULL); |
| 5435 const intptr_t previous_pos = |
| 5436 current_block_->scope->PreviousReferencePos(ident); |
| 5437 if (previous_pos >= 0) { |
| 5438 ASSERT(!script_.IsNull()); |
| 5439 if (previous_pos > ident_pos) { |
| 5440 ErrorMsg(ident_pos, |
| 5441 "initializer of '%s' may not refer to itself", |
| 5442 ident.ToCString()); |
| 5443 |
| 5444 } else { |
| 5445 intptr_t line_number; |
| 5446 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 5447 ErrorMsg(ident_pos, |
| 5448 "identifier '%s' previously used in line %" Pd "", |
| 5449 ident.ToCString(), |
| 5450 line_number); |
| 5451 } |
| 5452 } |
| 5453 |
| 5446 // Add variable to scope after parsing the initalizer expression. | 5454 // Add variable to scope after parsing the initalizer expression. |
| 5447 // The expression must not be able to refer to the variable. | 5455 // The expression must not be able to refer to the variable. |
| 5448 if (!current_block_->scope->AddVariable(variable)) { | 5456 if (!current_block_->scope->AddVariable(variable)) { |
| 5449 LocalVariable* existing_var = | 5457 LocalVariable* existing_var = |
| 5450 current_block_->scope->LookupVariable(variable->name(), true); | 5458 current_block_->scope->LookupVariable(variable->name(), true); |
| 5451 ASSERT(existing_var != NULL); | 5459 ASSERT(existing_var != NULL); |
| 5452 if (existing_var->owner() == current_block_->scope) { | 5460 if (existing_var->owner() == current_block_->scope) { |
| 5453 ErrorMsg(ident_pos, "identifier '%s' already defined", | 5461 ErrorMsg(ident_pos, "identifier '%s' already defined", |
| 5454 variable->name().ToCString()); | 5462 variable->name().ToCString()); |
| 5455 } else { | 5463 } else { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5550 ASSERT(CurrentToken() == Token::kLPAREN); | 5558 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5551 function_name = &Symbols::AnonymousClosure(); | 5559 function_name = &Symbols::AnonymousClosure(); |
| 5552 } else { | 5560 } else { |
| 5553 if (CurrentToken() == Token::kVOID) { | 5561 if (CurrentToken() == Token::kVOID) { |
| 5554 ConsumeToken(); | 5562 ConsumeToken(); |
| 5555 result_type = Type::VoidType(); | 5563 result_type = Type::VoidType(); |
| 5556 } else if ((CurrentToken() == Token::kIDENT) && | 5564 } else if ((CurrentToken() == Token::kIDENT) && |
| 5557 (LookaheadToken(1) != Token::kLPAREN)) { | 5565 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5558 result_type = ParseType(ClassFinalizer::kCanonicalize); | 5566 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 5559 } | 5567 } |
| 5568 const intptr_t name_pos = TokenPos(); |
| 5560 variable_name = ExpectIdentifier("function name expected"); | 5569 variable_name = ExpectIdentifier("function name expected"); |
| 5561 function_name = variable_name; | 5570 function_name = variable_name; |
| 5571 |
| 5572 // Check that the function name has not been referenced |
| 5573 // before this declaration. |
| 5574 ASSERT(current_block_ != NULL); |
| 5575 const intptr_t previous_pos = |
| 5576 current_block_->scope->PreviousReferencePos(*function_name); |
| 5577 if (previous_pos >= 0) { |
| 5578 ASSERT(!script_.IsNull()); |
| 5579 intptr_t line_number; |
| 5580 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 5581 ErrorMsg(name_pos, |
| 5582 "identifier '%s' previously used in line %" Pd "", |
| 5583 function_name->ToCString(), |
| 5584 line_number); |
| 5585 } |
| 5562 } | 5586 } |
| 5563 | 5587 |
| 5564 if (CurrentToken() != Token::kLPAREN) { | 5588 if (CurrentToken() != Token::kLPAREN) { |
| 5565 ErrorMsg("'(' expected"); | 5589 ErrorMsg("'(' expected"); |
| 5566 } | 5590 } |
| 5567 | 5591 |
| 5568 // Check whether we have parsed this closure function before, in a previous | 5592 // Check whether we have parsed this closure function before, in a previous |
| 5569 // compilation. If so, reuse the function object, else create a new one | 5593 // compilation. If so, reuse the function object, else create a new one |
| 5570 // and register it in the current class. | 5594 // and register it in the current class. |
| 5571 // Note that we cannot share the same closure function between the closurized | 5595 // Note that we cannot share the same closure function between the closurized |
| (...skipping 5183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10755 void Parser::SkipQualIdent() { | 10779 void Parser::SkipQualIdent() { |
| 10756 ASSERT(IsIdentifier()); | 10780 ASSERT(IsIdentifier()); |
| 10757 ConsumeToken(); | 10781 ConsumeToken(); |
| 10758 if (CurrentToken() == Token::kPERIOD) { | 10782 if (CurrentToken() == Token::kPERIOD) { |
| 10759 ConsumeToken(); // Consume the kPERIOD token. | 10783 ConsumeToken(); // Consume the kPERIOD token. |
| 10760 ExpectIdentifier("identifier expected after '.'"); | 10784 ExpectIdentifier("identifier expected after '.'"); |
| 10761 } | 10785 } |
| 10762 } | 10786 } |
| 10763 | 10787 |
| 10764 } // namespace dart | 10788 } // namespace dart |
| OLD | NEW |