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

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

Issue 1322973006: Symbols::NewFormatted and old space allocation. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address review comment Created 5 years, 3 months 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
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/symbols.h » ('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 "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 3769 matching lines...) Expand 10 before | Expand all | Expand 10 after
3780 // Redirected constructor: either this(...) or this.xxx(...). 3780 // Redirected constructor: either this(...) or this.xxx(...).
3781 is_redirecting = true; 3781 is_redirecting = true;
3782 if (method->params.has_field_initializer) { 3782 if (method->params.has_field_initializer) {
3783 // Constructors that redirect to another constructor must not 3783 // Constructors that redirect to another constructor must not
3784 // initialize any fields using field initializer parameters. 3784 // initialize any fields using field initializer parameters.
3785 ReportError(formal_param_pos, "Redirecting constructor " 3785 ReportError(formal_param_pos, "Redirecting constructor "
3786 "may not use field initializer parameters"); 3786 "may not use field initializer parameters");
3787 } 3787 }
3788 ConsumeToken(); // Colon. 3788 ConsumeToken(); // Colon.
3789 ExpectToken(Token::kTHIS); 3789 ExpectToken(Token::kTHIS);
3790 String& redir_name = String::ZoneHandle(Z, 3790 GrowableHandlePtrArray<const String> pieces(Z, 3);
3791 String::Concat(members->class_name(), Symbols::Dot())); 3791 pieces.Add(members->class_name());
3792 pieces.Add(Symbols::Dot());
3792 if (CurrentToken() == Token::kPERIOD) { 3793 if (CurrentToken() == Token::kPERIOD) {
3793 ConsumeToken(); 3794 ConsumeToken();
3794 redir_name = String::Concat(redir_name, 3795 pieces.Add(*ExpectIdentifier("constructor name expected"));
3795 *ExpectIdentifier("constructor name expected"));
3796 } 3796 }
3797 String& redir_name =
3798 String::ZoneHandle(Z, Symbols::FromConcatAll(pieces));
3799
3797 method->redirect_name = &redir_name; 3800 method->redirect_name = &redir_name;
3798 CheckToken(Token::kLPAREN); 3801 CheckToken(Token::kLPAREN);
3799 SkipToMatchingParenthesis(); 3802 SkipToMatchingParenthesis();
3800 } else { 3803 } else {
3801 SkipInitializers(); 3804 SkipInitializers();
3802 } 3805 }
3803 } 3806 }
3804 3807
3805 // Only constructors can redirect to another method. 3808 // Only constructors can redirect to another method.
3806 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); 3809 ASSERT((method->redirect_name == NULL) || method->IsConstructor());
(...skipping 2913 matching lines...) Expand 10 before | Expand all | Expand 10 after
6720 (found_func.token_pos() == async_func_pos) && 6723 (found_func.token_pos() == async_func_pos) &&
6721 (found_func.script() == innermost_function().script()) && 6724 (found_func.script() == innermost_function().script()) &&
6722 (found_func.parent_function() == innermost_function().raw())) { 6725 (found_func.parent_function() == innermost_function().raw())) {
6723 ASSERT(found_func.IsAsyncClosure()); 6726 ASSERT(found_func.IsAsyncClosure());
6724 closure = found_func.raw(); 6727 closure = found_func.raw();
6725 } else { 6728 } else {
6726 // Create the closure containing the body of this async function. 6729 // Create the closure containing the body of this async function.
6727 const String& async_func_name = 6730 const String& async_func_name =
6728 String::Handle(Z, innermost_function().name()); 6731 String::Handle(Z, innermost_function().name());
6729 String& closure_name = String::Handle(Z, 6732 String& closure_name = String::Handle(Z,
6730 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); 6733 Symbols::NewFormatted("<%s_async_body>", async_func_name.ToCString()));
6731 closure = Function::NewClosureFunction( 6734 closure = Function::NewClosureFunction(
6732 String::Handle(Z, Symbols::New(closure_name)), 6735 closure_name,
6733 innermost_function(), 6736 innermost_function(),
6734 async_func_pos); 6737 async_func_pos);
6735 closure.set_is_generated_body(true); 6738 closure.set_is_generated_body(true);
6736 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); 6739 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
6737 is_new_closure = true; 6740 is_new_closure = true;
6738 } 6741 }
6739 // Create the parameter list for the async body closure. 6742 // Create the parameter list for the async body closure.
6740 ParamList closure_params; 6743 ParamList closure_params;
6741 AddAsyncClosureParameters(&closure_params); 6744 AddAsyncClosureParameters(&closure_params);
6742 if (is_new_closure) { 6745 if (is_new_closure) {
(...skipping 1765 matching lines...) Expand 10 before | Expand all | Expand 10 after
8508 LocalVariable* var = 8511 LocalVariable* var =
8509 scope->LocalLookupVariable(Symbols::SavedTryContextVar()); 8512 scope->LocalLookupVariable(Symbols::SavedTryContextVar());
8510 ASSERT((var != NULL) && !var->is_captured()); 8513 ASSERT((var != NULL) && !var->is_captured());
8511 return var; 8514 return var;
8512 } 8515 }
8513 8516
8514 8517
8515 static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope, 8518 static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope,
8516 uint16_t try_index) { 8519 uint16_t try_index) {
8517 const String& async_saved_try_ctx_name = 8520 const String& async_saved_try_ctx_name =
8518 String::ZoneHandle(Symbols::New(String::Handle( 8521 String::ZoneHandle(Symbols::NewFormatted(
8519 String::NewFormatted( 8522 "%s%d",
8520 "%s%d", 8523 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
8521 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), 8524 try_index));
8522 try_index))));
8523 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); 8525 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name);
8524 ASSERT(var != NULL); 8526 ASSERT(var != NULL);
8525 return var; 8527 return var;
8526 } 8528 }
8527 8529
8528 8530
8529 // If the await or yield being parsed is in a try block, the continuation code 8531 // If the await or yield being parsed is in a try block, the continuation code
8530 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, 8532 // needs to restore the corresponding stack-based variable :saved_try_ctx_var,
8531 // and the stack-based variable :saved_try_ctx_var of the outer try block. 8533 // and the stack-based variable :saved_try_ctx_var of the outer try block.
8532 // The inner :saved_try_ctx_var is used by a finally clause handling an 8534 // The inner :saved_try_ctx_var is used by a finally clause handling an
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
8584 8586
8585 8587
8586 // Build an AST node for static call to Dart function print(str). 8588 // Build an AST node for static call to Dart function print(str).
8587 // Used during debugging to insert print in generated dart code. 8589 // Used during debugging to insert print in generated dart code.
8588 AstNode* Parser::DartPrint(const char* str) { 8590 AstNode* Parser::DartPrint(const char* str) {
8589 const Library& lib = Library::Handle(Library::CoreLibrary()); 8591 const Library& lib = Library::Handle(Library::CoreLibrary());
8590 const Function& print_fn = Function::ZoneHandle( 8592 const Function& print_fn = Function::ZoneHandle(
8591 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); 8593 Z, lib.LookupFunctionAllowPrivate(Symbols::print()));
8592 ASSERT(!print_fn.IsNull()); 8594 ASSERT(!print_fn.IsNull());
8593 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Scanner::kNoSourcePos); 8595 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
8594 String& msg = String::Handle(String::NewFormatted("%s", str)); 8596 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str));
8595 one_arg->Add(new(Z) LiteralNode(Scanner::kNoSourcePos, 8597 one_arg->Add(new(Z) LiteralNode(Scanner::kNoSourcePos, msg));
8596 String::ZoneHandle(Symbols::New(msg))));
8597 AstNode* print_call = 8598 AstNode* print_call =
8598 new(Z) StaticCallNode(Scanner::kNoSourcePos, print_fn, one_arg); 8599 new(Z) StaticCallNode(Scanner::kNoSourcePos, print_fn, one_arg);
8599 return print_call; 8600 return print_call;
8600 } 8601 }
8601 8602
8602 8603
8603 AstNode* Parser::ParseAwaitForStatement(String* label_name) { 8604 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
8604 TRACE_PARSER("ParseAwaitForStatement"); 8605 TRACE_PARSER("ParseAwaitForStatement");
8605 ASSERT(IsAwaitKeyword()); 8606 ASSERT(IsAwaitKeyword());
8606 const intptr_t await_for_pos = TokenPos(); 8607 const intptr_t await_for_pos = TokenPos();
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after
9536 // the chain of if/then/else handling all catch clauses. 9537 // the chain of if/then/else handling all catch clauses.
9537 async_code->Add(current); 9538 async_code->Add(current);
9538 current = async_code; 9539 current = async_code;
9539 } 9540 }
9540 return current; 9541 return current;
9541 } 9542 }
9542 9543
9543 9544
9544 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { 9545 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) {
9545 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, 9546 const String& async_saved_try_ctx_name = String::ZoneHandle(Z,
9546 Symbols::New(String::Handle(Z, 9547 Symbols::NewFormatted("%s%d",
9547 String::NewFormatted("%s%d", 9548 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
9548 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), 9549 last_used_try_index_ - 1));
9549 last_used_try_index_ - 1))));
9550 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( 9550 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
9551 Scanner::kNoSourcePos, 9551 Scanner::kNoSourcePos,
9552 async_saved_try_ctx_name, 9552 async_saved_try_ctx_name,
9553 Type::ZoneHandle(Z, Type::DynamicType())); 9553 Type::ZoneHandle(Z, Type::DynamicType()));
9554 ASSERT(async_temp_scope_ != NULL); 9554 ASSERT(async_temp_scope_ != NULL);
9555 async_temp_scope_->AddVariable(async_saved_try_ctx); 9555 async_temp_scope_->AddVariable(async_saved_try_ctx);
9556 ASSERT(saved_try_context != NULL); 9556 ASSERT(saved_try_context != NULL);
9557 current_block_->statements->Add(new(Z) StoreLocalNode( 9557 current_block_->statements->Add(new(Z) StoreLocalNode(
9558 Scanner::kNoSourcePos, 9558 Scanner::kNoSourcePos,
9559 async_saved_try_ctx, 9559 async_saved_try_ctx,
(...skipping 2380 matching lines...) Expand 10 before | Expand all | Expand 10 after
11940 } 11940 }
11941 11941
11942 11942
11943 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { 11943 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) {
11944 if (isolate()->object_store()->compile_time_constants() == Array::null()) { 11944 if (isolate()->object_store()->compile_time_constants() == Array::null()) {
11945 return false; 11945 return false;
11946 } 11946 }
11947 // We don't want to allocate anything in the heap here since this code 11947 // We don't want to allocate anything in the heap here since this code
11948 // is called from the optimizing compiler in the background thread. Allocate 11948 // is called from the optimizing compiler in the background thread. Allocate
11949 // the key value in the zone instead. 11949 // the key value in the zone instead.
11950 const char* key = Z->PrintToString("%s_%" Pd "", 11950 // const char* key = Z->PrintToString("%s_%" Pd "",
11951 String::Handle(Z, script_.url()).ToCString(), 11951 // String::Handle(Z, script_.url()).ToCString(),
11952 token_pos); 11952 // token_pos);
11953
11954 const String& key = String::Handle(Z,
11955 Symbols::NewFormatted("%s_%" Pd "",
11956 String::Handle(Z, script_.url()).ToCString(),
11957 token_pos));
11953 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); 11958 ConstantsMap constants(isolate()->object_store()->compile_time_constants());
11954 bool is_present = false; 11959 bool is_present = false;
11955 *value ^= constants.GetOrNull<const char *>(key, &is_present); 11960 *value ^= constants.GetOrNull(key, &is_present);
11956 ASSERT(constants.Release().raw() == 11961 ASSERT(constants.Release().raw() ==
11957 isolate()->object_store()->compile_time_constants()); 11962 isolate()->object_store()->compile_time_constants());
11958 if (FLAG_compiler_stats && is_present) { 11963 if (FLAG_compiler_stats && is_present) {
11959 isolate_->compiler_stats()->num_const_cache_hits++; 11964 isolate_->compiler_stats()->num_const_cache_hits++;
11960 } 11965 }
11961 return is_present; 11966 return is_present;
11962 } 11967 }
11963 11968
11964 11969
11965 RawInstance* Parser::TryCanonicalize(const Instance& instance, 11970 RawInstance* Parser::TryCanonicalize(const Instance& instance,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
12061 12066
12062 RawObject* Parser::EvaluateConstConstructorCall( 12067 RawObject* Parser::EvaluateConstConstructorCall(
12063 const Class& type_class, 12068 const Class& type_class,
12064 const TypeArguments& type_arguments, 12069 const TypeArguments& type_arguments,
12065 const Function& constructor, 12070 const Function& constructor,
12066 ArgumentListNode* arguments) { 12071 ArgumentListNode* arguments) {
12067 // Factories have one extra argument: the type arguments. 12072 // Factories have one extra argument: the type arguments.
12068 // Constructors have 2 extra arguments: rcvr and construction phase. 12073 // Constructors have 2 extra arguments: rcvr and construction phase.
12069 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; 12074 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2;
12070 const int num_arguments = arguments->length() + kNumExtraArgs; 12075 const int num_arguments = arguments->length() + kNumExtraArgs;
12071 const Array& arg_values = Array::Handle(Z, Array::New(num_arguments)); 12076 const Array& arg_values =
12077 Array::Handle(Z, Array::New(num_arguments, Heap::kOld));
12072 Instance& instance = Instance::Handle(Z); 12078 Instance& instance = Instance::Handle(Z);
12073 if (!constructor.IsFactory()) { 12079 if (!constructor.IsFactory()) {
12074 instance = Instance::New(type_class, Heap::kOld); 12080 instance = Instance::New(type_class, Heap::kOld);
12075 if (!type_arguments.IsNull()) { 12081 if (!type_arguments.IsNull()) {
12076 if (!type_arguments.IsInstantiated()) { 12082 if (!type_arguments.IsInstantiated()) {
12077 ReportError("type must be constant in const constructor"); 12083 ReportError("type must be constant in const constructor");
12078 } 12084 }
12079 instance.SetTypeArguments( 12085 instance.SetTypeArguments(
12080 TypeArguments::Handle(Z, type_arguments.Canonicalize())); 12086 TypeArguments::Handle(Z, type_arguments.Canonicalize()));
12081 } 12087 }
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after
13029 UnexpectedToken(); 13035 UnexpectedToken();
13030 } 13036 }
13031 return primary; 13037 return primary;
13032 } 13038 }
13033 13039
13034 13040
13035 AstNode* Parser::ParseSymbolLiteral() { 13041 AstNode* Parser::ParseSymbolLiteral() {
13036 ASSERT(CurrentToken() == Token::kHASH); 13042 ASSERT(CurrentToken() == Token::kHASH);
13037 ConsumeToken(); 13043 ConsumeToken();
13038 intptr_t symbol_pos = TokenPos(); 13044 intptr_t symbol_pos = TokenPos();
13039 String& symbol = String::Handle(Z); 13045 String& symbol = String::ZoneHandle(Z);
13040 if (IsIdentifier()) { 13046 if (IsIdentifier()) {
13041 symbol = CurrentLiteral()->raw(); 13047 symbol = CurrentLiteral()->raw();
13042 ConsumeToken(); 13048 ConsumeToken();
13049 GrowableHandlePtrArray<const String> pieces(Z, 3);
13050 pieces.Add(symbol);
13043 while (CurrentToken() == Token::kPERIOD) { 13051 while (CurrentToken() == Token::kPERIOD) {
13044 symbol = String::Concat(symbol, Symbols::Dot()); 13052 pieces.Add(Symbols::Dot());
13045 ConsumeToken(); 13053 ConsumeToken();
13046 symbol = String::Concat(symbol, 13054 pieces.Add(*ExpectIdentifier("identifier expected"));
13047 *ExpectIdentifier("identifier expected"));
13048 } 13055 }
13056 symbol = Symbols::FromConcatAll(pieces);
13049 } else if (Token::CanBeOverloaded(CurrentToken())) { 13057 } else if (Token::CanBeOverloaded(CurrentToken())) {
13050 symbol = String::New(Token::Str(CurrentToken())); 13058 symbol = Symbols::New(Token::Str(CurrentToken()));
13051 ConsumeToken(); 13059 ConsumeToken();
13052 } else { 13060 } else {
13053 ReportError("illegal symbol literal"); 13061 ReportError("illegal symbol literal");
13054 } 13062 }
13063 ASSERT(symbol.IsSymbol());
13055 13064
13056 Instance& symbol_instance = Instance::ZoneHandle(Z); 13065 Instance& symbol_instance = Instance::ZoneHandle(Z);
13057 if (GetCachedConstant(symbol_pos, &symbol_instance)) { 13066 if (GetCachedConstant(symbol_pos, &symbol_instance)) {
13058 return new(Z) LiteralNode(symbol_pos, symbol_instance); 13067 return new(Z) LiteralNode(symbol_pos, symbol_instance);
13059 } 13068 }
13060 13069
13061 // Call Symbol class constructor to create a symbol instance. 13070 // Call Symbol class constructor to create a symbol instance.
13062 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); 13071 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class());
13063 ASSERT(!symbol_class.IsNull()); 13072 ASSERT(!symbol_class.IsNull());
13064 ArgumentListNode* constr_args = new(Z) ArgumentListNode(symbol_pos); 13073 ArgumentListNode* constr_args = new(Z) ArgumentListNode(symbol_pos);
13065 constr_args->Add(new(Z) LiteralNode( 13074 constr_args->Add(new(Z) LiteralNode(symbol_pos, symbol));
13066 symbol_pos, String::ZoneHandle(Z, Symbols::New(symbol))));
13067 const Function& constr = Function::ZoneHandle(Z, 13075 const Function& constr = Function::ZoneHandle(Z,
13068 symbol_class.LookupConstructor(Symbols::SymbolCtor())); 13076 symbol_class.LookupConstructor(Symbols::SymbolCtor()));
13069 ASSERT(!constr.IsNull()); 13077 ASSERT(!constr.IsNull());
13070 const Object& result = Object::Handle(Z, 13078 const Object& result = Object::Handle(Z,
13071 EvaluateConstConstructorCall(symbol_class, 13079 EvaluateConstConstructorCall(symbol_class,
13072 TypeArguments::Handle(Z), 13080 TypeArguments::Handle(Z),
13073 constr, 13081 constr,
13074 constr_args)); 13082 constr_args));
13075 if (result.IsUnhandledException()) { 13083 if (result.IsUnhandledException()) {
13076 ReportErrors(Error::Cast(result), 13084 ReportErrors(Error::Cast(result),
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
13351 InvocationMirror::kMethod, 13359 InvocationMirror::kMethod,
13352 NULL); // No existing function. 13360 NULL); // No existing function.
13353 } else if (constructor.IsRedirectingFactory()) { 13361 } else if (constructor.IsRedirectingFactory()) {
13354 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); 13362 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
13355 Type& redirect_type = Type::Handle(Z, constructor.RedirectionType()); 13363 Type& redirect_type = Type::Handle(Z, constructor.RedirectionType());
13356 if (!redirect_type.IsMalformedOrMalbounded() && 13364 if (!redirect_type.IsMalformedOrMalbounded() &&
13357 !redirect_type.IsInstantiated()) { 13365 !redirect_type.IsInstantiated()) {
13358 // The type arguments of the redirection type are instantiated from the 13366 // The type arguments of the redirection type are instantiated from the
13359 // type arguments of the parsed type of the 'new' or 'const' expression. 13367 // type arguments of the parsed type of the 'new' or 'const' expression.
13360 Error& error = Error::Handle(Z); 13368 Error& error = Error::Handle(Z);
13361 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); 13369 redirect_type ^= redirect_type.InstantiateFrom(
13370 type_arguments,
13371 &error,
13372 NULL, // trail
13373 Heap::kOld);
13362 if (!error.IsNull()) { 13374 if (!error.IsNull()) {
13363 redirect_type = ClassFinalizer::NewFinalizedMalformedType( 13375 redirect_type = ClassFinalizer::NewFinalizedMalformedType(
13364 error, 13376 error,
13365 script_, 13377 script_,
13366 call_pos, 13378 call_pos,
13367 "redirecting factory type '%s' cannot be instantiated", 13379 "redirecting factory type '%s' cannot be instantiated",
13368 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); 13380 String::Handle(Z, redirect_type.UserVisibleName()).ToCString());
13369 } 13381 }
13370 } 13382 }
13371 if (!redirect_type.HasResolvedTypeClass()) { 13383 if (!redirect_type.HasResolvedTypeClass()) {
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
14288 void Parser::SkipQualIdent() { 14300 void Parser::SkipQualIdent() {
14289 ASSERT(IsIdentifier()); 14301 ASSERT(IsIdentifier());
14290 ConsumeToken(); 14302 ConsumeToken();
14291 if (CurrentToken() == Token::kPERIOD) { 14303 if (CurrentToken() == Token::kPERIOD) {
14292 ConsumeToken(); // Consume the kPERIOD token. 14304 ConsumeToken(); // Consume the kPERIOD token.
14293 ExpectIdentifier("identifier expected after '.'"); 14305 ExpectIdentifier("identifier expected after '.'");
14294 } 14306 }
14295 } 14307 }
14296 14308
14297 } // namespace dart 14309 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698