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

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

Issue 49253006: Compile time error on forward references to functions (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/socket_patch.dart ('k') | tests/co19/co19-co19.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/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
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
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
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
OLDNEW
« no previous file with comments | « runtime/bin/socket_patch.dart ('k') | tests/co19/co19-co19.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698