| 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/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 node_sequence = parser.ParseFunc(func, default_parameter_values); | 759 node_sequence = parser.ParseFunc(func, default_parameter_values); |
| 760 break; | 760 break; |
| 761 case RawFunction::kImplicitGetter: | 761 case RawFunction::kImplicitGetter: |
| 762 ASSERT(!func.is_static()); | 762 ASSERT(!func.is_static()); |
| 763 node_sequence = parser.ParseInstanceGetter(func); | 763 node_sequence = parser.ParseInstanceGetter(func); |
| 764 break; | 764 break; |
| 765 case RawFunction::kImplicitSetter: | 765 case RawFunction::kImplicitSetter: |
| 766 ASSERT(!func.is_static()); | 766 ASSERT(!func.is_static()); |
| 767 node_sequence = parser.ParseInstanceSetter(func); | 767 node_sequence = parser.ParseInstanceSetter(func); |
| 768 break; | 768 break; |
| 769 case RawFunction::kConstImplicitGetter: | 769 case RawFunction::kImplicitStaticFinalGetter: |
| 770 node_sequence = parser.ParseStaticConstGetter(func); | 770 node_sequence = parser.ParseStaticFinalGetter(func); |
| 771 break; | 771 break; |
| 772 case RawFunction::kMethodExtractor: | 772 case RawFunction::kMethodExtractor: |
| 773 node_sequence = parser.ParseMethodExtractor(func); | 773 node_sequence = parser.ParseMethodExtractor(func); |
| 774 break; | 774 break; |
| 775 case RawFunction::kNoSuchMethodDispatcher: | 775 case RawFunction::kNoSuchMethodDispatcher: |
| 776 node_sequence = | 776 node_sequence = |
| 777 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); | 777 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); |
| 778 break; | 778 break; |
| 779 case RawFunction::kInvokeFieldDispatcher: | 779 case RawFunction::kInvokeFieldDispatcher: |
| 780 node_sequence = | 780 node_sequence = |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 if (expr->EvalConstExpr() == NULL) { | 871 if (expr->EvalConstExpr() == NULL) { |
| 872 ErrorMsg(expr_pos, "expression must be a compile-time constant"); | 872 ErrorMsg(expr_pos, "expression must be a compile-time constant"); |
| 873 } | 873 } |
| 874 const Instance& val = EvaluateConstExpr(expr); | 874 const Instance& val = EvaluateConstExpr(expr); |
| 875 meta_values.Add(val); | 875 meta_values.Add(val); |
| 876 } | 876 } |
| 877 return Array::MakeArray(meta_values); | 877 return Array::MakeArray(meta_values); |
| 878 } | 878 } |
| 879 | 879 |
| 880 | 880 |
| 881 // TODO(regis): Since a const variable is implicitly final, | 881 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 882 // rename ParseStaticConstGetter to ParseStaticFinalGetter and | 882 TRACE_PARSER("ParseStaticFinalGetter"); |
| 883 // rename kConstImplicitGetter to kImplicitFinalGetter. | |
| 884 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { | |
| 885 TRACE_PARSER("ParseStaticConstGetter"); | |
| 886 ParamList params; | 883 ParamList params; |
| 887 ASSERT(func.num_fixed_parameters() == 0); // static. | 884 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 888 ASSERT(!func.HasOptionalParameters()); | 885 ASSERT(!func.HasOptionalParameters()); |
| 889 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 886 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 890 | 887 |
| 891 // Build local scope for function and populate with the formal parameters. | 888 // Build local scope for function and populate with the formal parameters. |
| 892 OpenFunctionBlock(func); | 889 OpenFunctionBlock(func); |
| 893 AddFormalParamsToScope(¶ms, current_block_->scope); | 890 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 894 | 891 |
| 895 intptr_t ident_pos = TokenPos(); | 892 intptr_t ident_pos = TokenPos(); |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1575 Resolver::ResolveDynamicAnyArgs(super_class, name)); | 1572 Resolver::ResolveDynamicAnyArgs(super_class, name)); |
| 1576 if (!super_func.IsNull() && | 1573 if (!super_func.IsNull() && |
| 1577 !super_func.AreValidArguments(arguments->length(), | 1574 !super_func.AreValidArguments(arguments->length(), |
| 1578 arguments->names(), | 1575 arguments->names(), |
| 1579 NULL)) { | 1576 NULL)) { |
| 1580 super_func = Function::null(); | 1577 super_func = Function::null(); |
| 1581 } else if (super_func.IsNull() && resolve_getter) { | 1578 } else if (super_func.IsNull() && resolve_getter) { |
| 1582 const String& getter_name = String::ZoneHandle(Field::GetterName(name)); | 1579 const String& getter_name = String::ZoneHandle(Field::GetterName(name)); |
| 1583 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); | 1580 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); |
| 1584 ASSERT(super_func.IsNull() || | 1581 ASSERT(super_func.IsNull() || |
| 1585 (super_func.kind() != RawFunction::kConstImplicitGetter)); | 1582 (super_func.kind() != RawFunction::kImplicitStaticFinalGetter)); |
| 1586 } | 1583 } |
| 1587 if (super_func.IsNull()) { | 1584 if (super_func.IsNull()) { |
| 1588 super_func = | 1585 super_func = |
| 1589 Resolver::ResolveDynamicAnyArgs(super_class, Symbols::NoSuchMethod()); | 1586 Resolver::ResolveDynamicAnyArgs(super_class, Symbols::NoSuchMethod()); |
| 1590 ASSERT(!super_func.IsNull()); | 1587 ASSERT(!super_func.IsNull()); |
| 1591 *is_no_such_method = true; | 1588 *is_no_such_method = true; |
| 1592 } else { | 1589 } else { |
| 1593 *is_no_such_method = false; | 1590 *is_no_such_method = false; |
| 1594 } | 1591 } |
| 1595 return super_func.raw(); | 1592 return super_func.raw(); |
| (...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3132 Function& setter = Function::Handle(); | 3129 Function& setter = Function::Handle(); |
| 3133 Field& class_field = Field::Handle(); | 3130 Field& class_field = Field::Handle(); |
| 3134 Instance& init_value = Instance::Handle(); | 3131 Instance& init_value = Instance::Handle(); |
| 3135 while (true) { | 3132 while (true) { |
| 3136 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3133 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3137 bool has_simple_literal = false; | 3134 bool has_simple_literal = false; |
| 3138 if (has_initializer) { | 3135 if (has_initializer) { |
| 3139 ConsumeToken(); | 3136 ConsumeToken(); |
| 3140 init_value = Object::sentinel().raw(); | 3137 init_value = Object::sentinel().raw(); |
| 3141 // For static const fields, the initialization expression | 3138 // For static const fields, the initialization expression |
| 3142 // will be parsed through the kConstImplicitGetter method | 3139 // will be parsed through the kImplicitStaticFinalGetter method |
| 3143 // invocation/compilation. | 3140 // invocation/compilation. |
| 3144 // For instance fields, the expression is parsed when a constructor | 3141 // For instance fields, the expression is parsed when a constructor |
| 3145 // is compiled. | 3142 // is compiled. |
| 3146 // For static const fields with very simple initializer expressions | 3143 // For static const fields with very simple initializer expressions |
| 3147 // (e.g. a literal number or string) we optimize away the | 3144 // (e.g. a literal number or string) we optimize away the |
| 3148 // kConstImplicitGetter and initialize the field here. | 3145 // kImplicitStaticFinalGetter and initialize the field here. |
| 3149 // We also do it for static final non-const fields, but only in production | 3146 // We also do it for static final non-const fields, but only in production |
| 3150 // mode. | 3147 // mode. |
| 3151 | 3148 |
| 3152 if (field->has_static && | 3149 if (field->has_static && |
| 3153 (field->has_const || | 3150 (field->has_const || |
| 3154 (!FLAG_enable_type_checks && field->has_final)) && | 3151 (!FLAG_enable_type_checks && field->has_final)) && |
| 3155 (LookaheadToken(1) == Token::kSEMICOLON)) { | 3152 (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 3156 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3153 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
| 3157 } | 3154 } |
| 3158 SkipExpr(); | 3155 SkipExpr(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3173 field->has_const, | 3170 field->has_const, |
| 3174 current_class(), | 3171 current_class(), |
| 3175 field->name_pos); | 3172 field->name_pos); |
| 3176 class_field.set_type(*field->type); | 3173 class_field.set_type(*field->type); |
| 3177 class_field.set_has_initializer(has_initializer); | 3174 class_field.set_has_initializer(has_initializer); |
| 3178 members->AddField(class_field); | 3175 members->AddField(class_field); |
| 3179 if (field->metadata_pos >= 0) { | 3176 if (field->metadata_pos >= 0) { |
| 3180 library_.AddFieldMetadata(class_field, field->metadata_pos); | 3177 library_.AddFieldMetadata(class_field, field->metadata_pos); |
| 3181 } | 3178 } |
| 3182 | 3179 |
| 3183 // For static const fields, set value to "uninitialized" and | 3180 // For static final fields (this includes static const fields), set value to |
| 3184 // create a kConstImplicitGetter getter method. | 3181 // "uninitialized" and create a kFinalImplicitGetter getter method. |
| 3185 if (field->has_static && has_initializer) { | 3182 if (field->has_static && has_initializer) { |
| 3186 class_field.set_value(init_value); | 3183 class_field.set_value(init_value); |
| 3187 if (!has_simple_literal) { | 3184 if (!has_simple_literal) { |
| 3188 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); | 3185 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
| 3189 getter = Function::New(getter_name, | 3186 getter = Function::New(getter_name, |
| 3190 RawFunction::kConstImplicitGetter, | 3187 RawFunction::kImplicitStaticFinalGetter, |
| 3191 field->has_static, | 3188 field->has_static, |
| 3192 field->has_const, | 3189 field->has_const, |
| 3193 /* is_abstract = */ false, | 3190 /* is_abstract = */ false, |
| 3194 /* is_external = */ false, | 3191 /* is_external = */ false, |
| 3195 current_class(), | 3192 current_class(), |
| 3196 field->name_pos); | 3193 field->name_pos); |
| 3197 getter.set_result_type(*field->type); | 3194 getter.set_result_type(*field->type); |
| 3198 members->AddFunction(getter); | 3195 members->AddFunction(getter); |
| 3199 } | 3196 } |
| 3200 } | 3197 } |
| (...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4298 if ((is_const || (!FLAG_enable_type_checks && is_final)) && | 4295 if ((is_const || (!FLAG_enable_type_checks && is_final)) && |
| 4299 (LookaheadToken(1) == Token::kSEMICOLON)) { | 4296 (LookaheadToken(1) == Token::kSEMICOLON)) { |
| 4300 has_simple_literal = IsSimpleLiteral(type, &field_value); | 4297 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 4301 } | 4298 } |
| 4302 SkipExpr(); | 4299 SkipExpr(); |
| 4303 field.set_value(field_value); | 4300 field.set_value(field_value); |
| 4304 if (!has_simple_literal) { | 4301 if (!has_simple_literal) { |
| 4305 // Create a static const getter. | 4302 // Create a static const getter. |
| 4306 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); | 4303 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); |
| 4307 getter = Function::New(getter_name, | 4304 getter = Function::New(getter_name, |
| 4308 RawFunction::kConstImplicitGetter, | 4305 RawFunction::kImplicitStaticFinalGetter, |
| 4309 is_static, | 4306 is_static, |
| 4310 is_const, | 4307 is_const, |
| 4311 /* is_abstract = */ false, | 4308 /* is_abstract = */ false, |
| 4312 /* is_external = */ false, | 4309 /* is_external = */ false, |
| 4313 current_class(), | 4310 current_class(), |
| 4314 name_pos); | 4311 name_pos); |
| 4315 getter.set_result_type(type); | 4312 getter.set_result_type(type); |
| 4316 top_level->functions.Add(getter); | 4313 top_level->functions.Add(getter); |
| 4317 } | 4314 } |
| 4318 } else if (is_final) { | 4315 } else if (is_final) { |
| (...skipping 3315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7634 // No field, check if we have an explicit getter function. | 7631 // No field, check if we have an explicit getter function. |
| 7635 const String& getter_name = | 7632 const String& getter_name = |
| 7636 String::ZoneHandle(Field::GetterName(func_name)); | 7633 String::ZoneHandle(Field::GetterName(func_name)); |
| 7637 const int kNumArguments = 0; // no arguments. | 7634 const int kNumArguments = 0; // no arguments. |
| 7638 func = Resolver::ResolveStatic(cls, | 7635 func = Resolver::ResolveStatic(cls, |
| 7639 getter_name, | 7636 getter_name, |
| 7640 kNumArguments, | 7637 kNumArguments, |
| 7641 Object::empty_array(), | 7638 Object::empty_array(), |
| 7642 Resolver::kIsQualified); | 7639 Resolver::kIsQualified); |
| 7643 if (!func.IsNull()) { | 7640 if (!func.IsNull()) { |
| 7644 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 7641 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 7645 EnsureSavedCurrentContext(); | 7642 EnsureSavedCurrentContext(); |
| 7646 closure = new StaticGetterNode(call_pos, | 7643 closure = new StaticGetterNode(call_pos, |
| 7647 NULL, | 7644 NULL, |
| 7648 false, | 7645 false, |
| 7649 Class::ZoneHandle(cls.raw()), | 7646 Class::ZoneHandle(cls.raw()), |
| 7650 func_name); | 7647 func_name); |
| 7651 return new ClosureCallNode(call_pos, closure, arguments); | 7648 return new ClosureCallNode(call_pos, closure, arguments); |
| 7652 } | 7649 } |
| 7653 } else { | 7650 } else { |
| 7654 EnsureSavedCurrentContext(); | 7651 EnsureSavedCurrentContext(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7716 ASSERT(field.is_static()); | 7713 ASSERT(field.is_static()); |
| 7717 const Class& field_owner = Class::ZoneHandle(field.owner()); | 7714 const Class& field_owner = Class::ZoneHandle(field.owner()); |
| 7718 const String& field_name = String::ZoneHandle(field.name()); | 7715 const String& field_name = String::ZoneHandle(field.name()); |
| 7719 const String& getter_name = String::Handle(Field::GetterName(field_name)); | 7716 const String& getter_name = String::Handle(Field::GetterName(field_name)); |
| 7720 const Function& getter = | 7717 const Function& getter = |
| 7721 Function::Handle(field_owner.LookupStaticFunction(getter_name)); | 7718 Function::Handle(field_owner.LookupStaticFunction(getter_name)); |
| 7722 // Never load field directly if there is a getter (deterministic AST). | 7719 // Never load field directly if there is a getter (deterministic AST). |
| 7723 if (getter.IsNull()) { | 7720 if (getter.IsNull()) { |
| 7724 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); | 7721 return new LoadStaticFieldNode(ident_pos, Field::ZoneHandle(field.raw())); |
| 7725 } else { | 7722 } else { |
| 7726 ASSERT(getter.kind() == RawFunction::kConstImplicitGetter); | 7723 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 7727 return new StaticGetterNode(ident_pos, | 7724 return new StaticGetterNode(ident_pos, |
| 7728 NULL, // Receiver. | 7725 NULL, // Receiver. |
| 7729 false, // is_super_getter. | 7726 false, // is_super_getter. |
| 7730 field_owner, | 7727 field_owner, |
| 7731 field_name); | 7728 field_name); |
| 7732 } | 7729 } |
| 7733 } | 7730 } |
| 7734 | 7731 |
| 7735 | 7732 |
| 7736 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 7733 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7801 if (func.IsNull()) { | 7798 if (func.IsNull()) { |
| 7802 // No field or explicit getter function, throw a NoSuchMethodError. | 7799 // No field or explicit getter function, throw a NoSuchMethodError. |
| 7803 return ThrowNoSuchMethodError(ident_pos, | 7800 return ThrowNoSuchMethodError(ident_pos, |
| 7804 cls, | 7801 cls, |
| 7805 field_name, | 7802 field_name, |
| 7806 InvocationMirror::kStatic, | 7803 InvocationMirror::kStatic, |
| 7807 InvocationMirror::kGetter); | 7804 InvocationMirror::kGetter); |
| 7808 } | 7805 } |
| 7809 access = CreateImplicitClosureNode(func, call_pos, NULL); | 7806 access = CreateImplicitClosureNode(func, call_pos, NULL); |
| 7810 } else { | 7807 } else { |
| 7811 ASSERT(func.kind() != RawFunction::kConstImplicitGetter); | 7808 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 7812 access = new StaticGetterNode(call_pos, | 7809 access = new StaticGetterNode(call_pos, |
| 7813 NULL, | 7810 NULL, |
| 7814 false, | 7811 false, |
| 7815 Class::ZoneHandle(cls.raw()), | 7812 Class::ZoneHandle(cls.raw()), |
| 7816 field_name); | 7813 field_name); |
| 7817 } | 7814 } |
| 7818 } else { | 7815 } else { |
| 7819 access = GenerateStaticFieldLookup(field, TokenPos()); | 7816 access = GenerateStaticFieldLookup(field, TokenPos()); |
| 7820 } | 7817 } |
| 7821 } | 7818 } |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8364 if (field.is_const()) { | 8361 if (field.is_const()) { |
| 8365 field.set_value(Object::transition_sentinel()); | 8362 field.set_value(Object::transition_sentinel()); |
| 8366 const int kNumArguments = 0; // no arguments. | 8363 const int kNumArguments = 0; // no arguments. |
| 8367 const Function& func = | 8364 const Function& func = |
| 8368 Function::Handle(Resolver::ResolveStatic(field_owner, | 8365 Function::Handle(Resolver::ResolveStatic(field_owner, |
| 8369 getter_name, | 8366 getter_name, |
| 8370 kNumArguments, | 8367 kNumArguments, |
| 8371 Object::empty_array(), | 8368 Object::empty_array(), |
| 8372 Resolver::kIsQualified)); | 8369 Resolver::kIsQualified)); |
| 8373 ASSERT(!func.IsNull()); | 8370 ASSERT(!func.IsNull()); |
| 8374 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 8371 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 8375 Object& const_value = Object::Handle( | 8372 Object& const_value = Object::Handle( |
| 8376 DartEntry::InvokeFunction(func, Object::empty_array())); | 8373 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 8377 if (const_value.IsError()) { | 8374 if (const_value.IsError()) { |
| 8378 const Error& error = Error::Cast(const_value); | 8375 const Error& error = Error::Cast(const_value); |
| 8379 if (error.IsUnhandledException()) { | 8376 if (error.IsUnhandledException()) { |
| 8380 // An exception may not occur in every parse attempt, i.e., the | 8377 // An exception may not occur in every parse attempt, i.e., the |
| 8381 // generated AST is not deterministic. Therefore mark the function as | 8378 // generated AST is not deterministic. Therefore mark the function as |
| 8382 // not optimizable. | 8379 // not optimizable. |
| 8383 current_function().set_is_optimizable(false); | 8380 current_function().set_is_optimizable(false); |
| 8384 field.set_value(Object::null_instance()); | 8381 field.set_value(Object::null_instance()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 8398 field.set_value(instance); | 8395 field.set_value(instance); |
| 8399 return NULL; // Constant | 8396 return NULL; // Constant |
| 8400 } else { | 8397 } else { |
| 8401 return new StaticGetterNode(TokenPos(), | 8398 return new StaticGetterNode(TokenPos(), |
| 8402 NULL, | 8399 NULL, |
| 8403 false, | 8400 false, |
| 8404 field_owner, | 8401 field_owner, |
| 8405 field_name); | 8402 field_name); |
| 8406 } | 8403 } |
| 8407 } | 8404 } |
| 8408 if (getter.IsNull() || (getter.kind() == RawFunction::kConstImplicitGetter)) { | 8405 if (getter.IsNull() || |
| 8406 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
| 8409 return NULL; | 8407 return NULL; |
| 8410 } | 8408 } |
| 8411 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 8409 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 8412 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); | 8410 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); |
| 8413 } | 8411 } |
| 8414 | 8412 |
| 8415 | 8413 |
| 8416 RawObject* Parser::EvaluateConstConstructorCall( | 8414 RawObject* Parser::EvaluateConstConstructorCall( |
| 8417 const Class& type_class, | 8415 const Class& type_class, |
| 8418 const AbstractTypeArguments& type_arguments, | 8416 const AbstractTypeArguments& type_arguments, |
| (...skipping 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10204 void Parser::SkipQualIdent() { | 10202 void Parser::SkipQualIdent() { |
| 10205 ASSERT(IsIdentifier()); | 10203 ASSERT(IsIdentifier()); |
| 10206 ConsumeToken(); | 10204 ConsumeToken(); |
| 10207 if (CurrentToken() == Token::kPERIOD) { | 10205 if (CurrentToken() == Token::kPERIOD) { |
| 10208 ConsumeToken(); // Consume the kPERIOD token. | 10206 ConsumeToken(); // Consume the kPERIOD token. |
| 10209 ExpectIdentifier("identifier expected after '.'"); | 10207 ExpectIdentifier("identifier expected after '.'"); |
| 10210 } | 10208 } |
| 10211 } | 10209 } |
| 10212 | 10210 |
| 10213 } // namespace dart | 10211 } // namespace dart |
| OLD | NEW |