| Index: dart/runtime/vm/parser.cc
|
| ===================================================================
|
| --- dart/runtime/vm/parser.cc (revision 29808)
|
| +++ dart/runtime/vm/parser.cc (working copy)
|
| @@ -4839,8 +4839,8 @@
|
|
|
|
|
| RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag,
|
| - intptr_t token_pos,
|
| - const String& url) {
|
| + intptr_t token_pos,
|
| + const String& url) {
|
| Dart_LibraryTagHandler handler = isolate()->library_tag_handler();
|
| if (handler == NULL) {
|
| if (url.StartsWith(Symbols::DartScheme())) {
|
| @@ -5408,10 +5408,8 @@
|
| TRACE_PARSER("ParseVariableDeclaration");
|
| ASSERT(IsIdentifier());
|
| const intptr_t ident_pos = TokenPos();
|
| - LocalVariable* variable =
|
| - new LocalVariable(ident_pos, *CurrentLiteral(), type);
|
| - ASSERT(current_block_ != NULL);
|
| - ASSERT(current_block_->scope != NULL);
|
| + const String& ident = *CurrentLiteral();
|
| + LocalVariable* variable = new LocalVariable(ident_pos, ident, type);
|
| ConsumeToken(); // Variable identifier.
|
| AstNode* initialization = NULL;
|
| if (CurrentToken() == Token::kASSIGN) {
|
| @@ -5432,6 +5430,27 @@
|
| AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle());
|
| initialization = new StoreLocalNode(ident_pos, variable, null_expr);
|
| }
|
| +
|
| + ASSERT(current_block_ != NULL);
|
| + const intptr_t previous_pos =
|
| + current_block_->scope->PreviousReferencePos(ident);
|
| + if (previous_pos >= 0) {
|
| + ASSERT(!script_.IsNull());
|
| + if (previous_pos > ident_pos) {
|
| + ErrorMsg(ident_pos,
|
| + "initializer of '%s' may not refer to itself",
|
| + ident.ToCString());
|
| +
|
| + } else {
|
| + intptr_t line_number;
|
| + script_.GetTokenLocation(previous_pos, &line_number, NULL);
|
| + ErrorMsg(ident_pos,
|
| + "identifier '%s' previously used in line %" Pd "",
|
| + ident.ToCString(),
|
| + line_number);
|
| + }
|
| + }
|
| +
|
| // Add variable to scope after parsing the initalizer expression.
|
| // The expression must not be able to refer to the variable.
|
| if (!current_block_->scope->AddVariable(variable)) {
|
| @@ -5546,8 +5565,24 @@
|
| (LookaheadToken(1) != Token::kLPAREN)) {
|
| result_type = ParseType(ClassFinalizer::kCanonicalize);
|
| }
|
| + const intptr_t name_pos = TokenPos();
|
| variable_name = ExpectIdentifier("function name expected");
|
| function_name = variable_name;
|
| +
|
| + // Check that the function name has not been referenced
|
| + // before this declaration.
|
| + ASSERT(current_block_ != NULL);
|
| + const intptr_t previous_pos =
|
| + current_block_->scope->PreviousReferencePos(*function_name);
|
| + if (previous_pos >= 0) {
|
| + ASSERT(!script_.IsNull());
|
| + intptr_t line_number;
|
| + script_.GetTokenLocation(previous_pos, &line_number, NULL);
|
| + ErrorMsg(name_pos,
|
| + "identifier '%s' previously used in line %" Pd "",
|
| + function_name->ToCString(),
|
| + line_number);
|
| + }
|
| }
|
|
|
| if (CurrentToken() != Token::kLPAREN) {
|
| @@ -8918,6 +8953,9 @@
|
| TRACE_PARSER("ResolveIdentInLocalScope");
|
| // First try to find the identifier in the nested local scopes.
|
| LocalVariable* local = LookupLocalScope(ident);
|
| + if (current_block_ != NULL) {
|
| + current_block_->scope->AddReferencedName(ident_pos, ident);
|
| + }
|
| if (local != NULL) {
|
| if (node != NULL) {
|
| if (local->IsConst()) {
|
| @@ -9262,6 +9300,11 @@
|
| }
|
| QualIdent type_name;
|
| if (finalization == ClassFinalizer::kIgnore) {
|
| + if (!is_top_level_ && (current_block_ != NULL)) {
|
| + // Add the library prefix or type class name to the list of referenced
|
| + // names of this scope, even if the type is ignored.
|
| + current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral());
|
| + }
|
| SkipQualIdent();
|
| } else {
|
| ParseQualIdent(&type_name);
|
|
|