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

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

Issue 51533003: Compile time error if name is used before variable is declared (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
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 5242 matching lines...) Expand 10 before | Expand all | Expand 10 after
5253 } 5253 }
5254 5254
5255 5255
5256 // Returns ast nodes of the variable initialization. 5256 // Returns ast nodes of the variable initialization.
5257 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, 5257 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type,
5258 bool is_final, 5258 bool is_final,
5259 bool is_const) { 5259 bool is_const) {
5260 TRACE_PARSER("ParseVariableDeclaration"); 5260 TRACE_PARSER("ParseVariableDeclaration");
5261 ASSERT(IsIdentifier()); 5261 ASSERT(IsIdentifier());
5262 const intptr_t ident_pos = TokenPos(); 5262 const intptr_t ident_pos = TokenPos();
5263 LocalVariable* variable = 5263 const String& ident = *CurrentLiteral();
5264 new LocalVariable(ident_pos, *CurrentLiteral(), type); 5264 LocalVariable* variable = new LocalVariable(ident_pos, ident, type);
5265 ASSERT(current_block_ != NULL); 5265 ASSERT(current_block_ != NULL);
5266 ASSERT(current_block_->scope != NULL); 5266 ASSERT(current_block_->scope != NULL);
5267 const intptr_t previous_pos =
5268 current_block_->scope->PreviousReferencePos(ident);
5269 if (previous_pos >= 0) {
5270 ASSERT(!script_.IsNull());
5271 if (script_.HasSource()) {
5272 intptr_t line_number;
5273 script_.GetTokenLocation(previous_pos, &line_number, NULL);
Ivan Posva 2013/11/01 16:35:12 Since we are only getting the line number here we
hausner 2013/11/01 16:42:51 True. I figured line numbers make less sense if a
5274 ErrorMsg(ident_pos,
5275 "identifier '%s' previously used in line %" Pd "",
5276 ident.ToCString(),
5277 line_number);
5278 } else {
5279 ErrorMsg(ident_pos,
5280 "identifier '%s' previously used in this scope",
5281 ident.ToCString());
5282 }
5283 }
5267 ConsumeToken(); // Variable identifier. 5284 ConsumeToken(); // Variable identifier.
5268 AstNode* initialization = NULL; 5285 AstNode* initialization = NULL;
5269 if (CurrentToken() == Token::kASSIGN) { 5286 if (CurrentToken() == Token::kASSIGN) {
5270 // Variable initialization. 5287 // Variable initialization.
5271 const intptr_t assign_pos = TokenPos(); 5288 const intptr_t assign_pos = TokenPos();
5272 ConsumeToken(); 5289 ConsumeToken();
5273 AstNode* expr = ParseExpr(is_const, kConsumeCascades); 5290 AstNode* expr = ParseExpr(is_const, kConsumeCascades);
5274 initialization = new StoreLocalNode(assign_pos, variable, expr); 5291 initialization = new StoreLocalNode(assign_pos, variable, expr);
5275 if (is_const) { 5292 if (is_const) {
5276 ASSERT(expr->IsLiteralNode()); 5293 ASSERT(expr->IsLiteralNode());
(...skipping 3492 matching lines...) Expand 10 before | Expand all | Expand 10 after
8769 8786
8770 // Do a lookup for the identifier in the block scope and the class scope 8787 // Do a lookup for the identifier in the block scope and the class scope
8771 // return true if the identifier is found, false otherwise. 8788 // return true if the identifier is found, false otherwise.
8772 // If node is non NULL return an AST node corresponding to the identifier. 8789 // If node is non NULL return an AST node corresponding to the identifier.
8773 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8790 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8774 const String &ident, 8791 const String &ident,
8775 AstNode** node) { 8792 AstNode** node) {
8776 TRACE_PARSER("ResolveIdentInLocalScope"); 8793 TRACE_PARSER("ResolveIdentInLocalScope");
8777 // First try to find the identifier in the nested local scopes. 8794 // First try to find the identifier in the nested local scopes.
8778 LocalVariable* local = LookupLocalScope(ident); 8795 LocalVariable* local = LookupLocalScope(ident);
8796 if (current_block_ != NULL) {
8797 current_block_->scope->AddReferencedName(ident_pos, ident);
8798 }
8779 if (local != NULL) { 8799 if (local != NULL) {
8780 if (node != NULL) { 8800 if (node != NULL) {
8781 if (local->IsConst()) { 8801 if (local->IsConst()) {
8782 *node = new LiteralNode(ident_pos, *local->ConstValue()); 8802 *node = new LiteralNode(ident_pos, *local->ConstValue());
8783 } else { 8803 } else {
8784 *node = new LoadLocalNode(ident_pos, local); 8804 *node = new LoadLocalNode(ident_pos, local);
8785 } 8805 }
8786 } 8806 }
8787 return true; 8807 return true;
8788 } 8808 }
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
9113 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and 9133 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and
9114 // finalize it according to the given type finalization mode. 9134 // finalize it according to the given type finalization mode.
9115 RawAbstractType* Parser::ParseType( 9135 RawAbstractType* Parser::ParseType(
9116 ClassFinalizer::FinalizationKind finalization) { 9136 ClassFinalizer::FinalizationKind finalization) {
9117 TRACE_PARSER("ParseType"); 9137 TRACE_PARSER("ParseType");
9118 if (CurrentToken() != Token::kIDENT) { 9138 if (CurrentToken() != Token::kIDENT) {
9119 ErrorMsg("type name expected"); 9139 ErrorMsg("type name expected");
9120 } 9140 }
9121 QualIdent type_name; 9141 QualIdent type_name;
9122 if (finalization == ClassFinalizer::kIgnore) { 9142 if (finalization == ClassFinalizer::kIgnore) {
9143 if (!is_top_level_ && (current_block_ != NULL)) {
9144 // Add the library prefix or type class name to the list of referenced
9145 // names of this scope, even if the type is ignored.
9146 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral());
9147 }
9123 SkipQualIdent(); 9148 SkipQualIdent();
9124 } else { 9149 } else {
9125 ParseQualIdent(&type_name); 9150 ParseQualIdent(&type_name);
9126 // An identifier cannot be resolved in a local scope when top level parsing. 9151 // An identifier cannot be resolved in a local scope when top level parsing.
9127 if (!is_top_level_ && 9152 if (!is_top_level_ &&
9128 (type_name.lib_prefix == NULL) && 9153 (type_name.lib_prefix == NULL) &&
9129 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { 9154 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) {
9130 // The type is malformed. Skip over its type arguments. 9155 // The type is malformed. Skip over its type arguments.
9131 ParseTypeArguments(ClassFinalizer::kIgnore); 9156 ParseTypeArguments(ClassFinalizer::kIgnore);
9132 if (finalization == ClassFinalizer::kCanonicalizeWellFormed) { 9157 if (finalization == ClassFinalizer::kCanonicalizeWellFormed) {
(...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after
10594 void Parser::SkipQualIdent() { 10619 void Parser::SkipQualIdent() {
10595 ASSERT(IsIdentifier()); 10620 ASSERT(IsIdentifier());
10596 ConsumeToken(); 10621 ConsumeToken();
10597 if (CurrentToken() == Token::kPERIOD) { 10622 if (CurrentToken() == Token::kPERIOD) {
10598 ConsumeToken(); // Consume the kPERIOD token. 10623 ConsumeToken(); // Consume the kPERIOD token.
10599 ExpectIdentifier("identifier expected after '.'"); 10624 ExpectIdentifier("identifier expected after '.'");
10600 } 10625 }
10601 } 10626 }
10602 10627
10603 } // namespace dart 10628 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/typed_data.dart ('k') | runtime/vm/scopes.h » ('j') | runtime/vm/scopes.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698