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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { | 112 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { |
113 return new LocalVariable(token_pos, | 113 return new LocalVariable(token_pos, |
114 Symbols::ExprTemp(), | 114 Symbols::ExprTemp(), |
115 Type::ZoneHandle(Type::DynamicType())); | 115 Type::ZoneHandle(Type::DynamicType())); |
116 } | 116 } |
117 | 117 |
118 | 118 |
119 LocalVariable* ParsedFunction::CreateArrayLiteralVar(intptr_t token_pos) { | |
120 return new LocalVariable(token_pos, | |
121 Symbols::ArrayLiteralVar(), | |
122 Type::ZoneHandle(Type::ArrayType())); | |
123 } | |
124 | |
125 | |
126 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 119 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
127 ASSERT(node_sequence_ == NULL); | 120 ASSERT(node_sequence_ == NULL); |
128 ASSERT(node_sequence != NULL); | 121 ASSERT(node_sequence != NULL); |
129 node_sequence_ = node_sequence; | 122 node_sequence_ = node_sequence; |
130 } | 123 } |
131 | 124 |
132 | 125 |
133 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const { | 126 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const { |
134 const int num_parameters = function().NumParameters(); | 127 const int num_parameters = function().NumParameters(); |
135 LocalScope* scope = node_sequence()->scope(); | 128 LocalScope* scope = node_sequence()->scope(); |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 case RawFunction::kConstImplicitGetter: | 774 case RawFunction::kConstImplicitGetter: |
782 node_sequence = parser.ParseStaticConstGetter(func); | 775 node_sequence = parser.ParseStaticConstGetter(func); |
783 break; | 776 break; |
784 case RawFunction::kMethodExtractor: | 777 case RawFunction::kMethodExtractor: |
785 node_sequence = parser.ParseMethodExtractor(func); | 778 node_sequence = parser.ParseMethodExtractor(func); |
786 break; | 779 break; |
787 default: | 780 default: |
788 UNREACHABLE(); | 781 UNREACHABLE(); |
789 } | 782 } |
790 | 783 |
791 parsed_function->set_array_literal_var( | |
792 ParsedFunction::CreateArrayLiteralVar(func.token_pos())); | |
793 node_sequence->scope()->AddVariable(parsed_function->array_literal_var()); | |
794 | |
795 if (!HasReturnNode(node_sequence)) { | 784 if (!HasReturnNode(node_sequence)) { |
796 // Add implicit return node. | 785 // Add implicit return node. |
797 node_sequence->Add(new ReturnNode(func.end_token_pos())); | 786 node_sequence->Add(new ReturnNode(func.end_token_pos())); |
798 } | 787 } |
799 if (parsed_function->has_expression_temp_var()) { | 788 if (parsed_function->has_expression_temp_var()) { |
800 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 789 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
801 } | 790 } |
802 if (parsed_function->has_saved_current_context_var()) { | 791 if (parsed_function->has_saved_current_context_var()) { |
803 node_sequence->scope()->AddVariable( | 792 node_sequence->scope()->AddVariable( |
804 parsed_function->saved_current_context_var()); | 793 parsed_function->saved_current_context_var()); |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1402 } | 1391 } |
1403 | 1392 |
1404 | 1393 |
1405 static const String& PrivateCoreLibName(const String& str) { | 1394 static const String& PrivateCoreLibName(const String& str) { |
1406 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1395 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
1407 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); | 1396 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); |
1408 return private_name; | 1397 return private_name; |
1409 } | 1398 } |
1410 | 1399 |
1411 | 1400 |
1412 LocalVariable* Parser::BuildArrayTempLocal(intptr_t token_pos) { | |
1413 char name[64]; | |
1414 OS::SNPrint(name, 64, ":arrlit%"Pd, token_pos); | |
1415 LocalVariable* temp = | |
1416 new LocalVariable(token_pos, | |
1417 String::ZoneHandle(Symbols::New(name)), | |
1418 Type::ZoneHandle(Type::ArrayType())); | |
1419 current_block_->scope->AddVariable(temp); | |
1420 return temp; | |
1421 } | |
1422 | |
1423 | |
1424 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 1401 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
1425 intptr_t call_pos, | 1402 intptr_t call_pos, |
1426 const String& function_name, | 1403 const String& function_name, |
1427 const ArgumentListNode& function_args) { | 1404 const ArgumentListNode& function_args) { |
1428 const intptr_t args_pos = function_args.token_pos(); | 1405 const intptr_t args_pos = function_args.token_pos(); |
1429 // Build arguments to the call to the static | 1406 // Build arguments to the call to the static |
1430 // InvocationMirror._allocateInvocationMirror method. | 1407 // InvocationMirror._allocateInvocationMirror method. |
1431 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 1408 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
1432 // The first argument is the original function name. | 1409 // The first argument is the original function name. |
1433 arguments->Add(new LiteralNode(args_pos, function_name)); | 1410 arguments->Add(new LiteralNode(args_pos, function_name)); |
1434 // The second argument is the arguments descriptor of the original function. | 1411 // The second argument is the arguments descriptor of the original function. |
1435 const Array& args_descriptor = | 1412 const Array& args_descriptor = |
1436 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 1413 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), |
1437 function_args.names())); | 1414 function_args.names())); |
1438 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 1415 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
1439 // The third argument is an array containing the original function arguments, | 1416 // The third argument is an array containing the original function arguments, |
1440 // including the receiver. | 1417 // including the receiver. |
1441 ArrayNode* args_array = new ArrayNode( | 1418 ArrayNode* args_array = |
1442 args_pos, Type::ZoneHandle(Type::ArrayType()), | 1419 new ArrayNode(args_pos, Type::ZoneHandle(Type::ArrayType())); |
1443 *BuildArrayTempLocal(call_pos)); | |
1444 for (intptr_t i = 0; i < function_args.length(); i++) { | 1420 for (intptr_t i = 0; i < function_args.length(); i++) { |
1445 args_array->AddElement(function_args.NodeAt(i)); | 1421 args_array->AddElement(function_args.NodeAt(i)); |
1446 } | 1422 } |
1447 arguments->Add(args_array); | 1423 arguments->Add(args_array); |
1448 // Lookup the static InvocationMirror._allocateInvocationMirror method. | 1424 // Lookup the static InvocationMirror._allocateInvocationMirror method. |
1449 const Class& mirror_class = | 1425 const Class& mirror_class = |
1450 Class::Handle(LookupCoreClass(Symbols::InvocationMirror())); | 1426 Class::Handle(LookupCoreClass(Symbols::InvocationMirror())); |
1451 ASSERT(!mirror_class.IsNull()); | 1427 ASSERT(!mirror_class.IsNull()); |
1452 const Function& allocation_function = Function::ZoneHandle( | 1428 const Function& allocation_function = Function::ZoneHandle( |
1453 mirror_class.LookupStaticFunction( | 1429 mirror_class.LookupStaticFunction( |
(...skipping 6298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7752 return left; | 7728 return left; |
7753 } | 7729 } |
7754 ASSERT(selector != NULL); | 7730 ASSERT(selector != NULL); |
7755 left = selector; | 7731 left = selector; |
7756 } | 7732 } |
7757 } | 7733 } |
7758 | 7734 |
7759 | 7735 |
7760 AstNode* Parser::ParsePostfixExpr() { | 7736 AstNode* Parser::ParsePostfixExpr() { |
7761 TRACE_PARSER("ParsePostfixExpr"); | 7737 TRACE_PARSER("ParsePostfixExpr"); |
7762 const intptr_t postfix_expr_pos = TokenPos(); | 7738 const intptr_t token_pos = TokenPos(); |
hausner
2013/05/28 17:00:47
Why are you renaming this? The old name expresses
Florian Schneider
2013/05/30 09:29:31
I found it too long so that it caused some ugly li
| |
7763 AstNode* postfix_expr = ParsePrimary(); | 7739 AstNode* postfix_expr = ParsePrimary(); |
7764 postfix_expr = ParseSelectors(postfix_expr, false); | 7740 postfix_expr = ParseSelectors(postfix_expr, false); |
7765 if (IsIncrementOperator(CurrentToken())) { | 7741 if (IsIncrementOperator(CurrentToken())) { |
7766 TRACE_PARSER("IncrementOperator"); | 7742 TRACE_PARSER("IncrementOperator"); |
7767 Token::Kind incr_op = CurrentToken(); | 7743 Token::Kind incr_op = CurrentToken(); |
7768 if (!IsAssignableExpr(postfix_expr)) { | 7744 if (!IsAssignableExpr(postfix_expr)) { |
7769 ErrorMsg("expression is not assignable"); | 7745 ErrorMsg("expression is not assignable"); |
7770 } | 7746 } |
7771 ConsumeToken(); | 7747 ConsumeToken(); |
7772 // Not prefix. | 7748 // Not prefix. |
7749 if (postfix_expr->IsInstanceGetterNode()) { | |
hausner
2013/05/28 17:00:47
I think this special case needs to be handled in P
Florian Schneider
2013/05/30 09:29:31
Yes, I'll handle this and the other cases in Prepa
| |
7750 InstanceGetterNode* getter = postfix_expr->AsInstanceGetterNode(); | |
7751 Token::Kind binary_op = | |
7752 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | |
7753 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { | |
7754 LetNode* result = new LetNode(token_pos, 2); | |
7755 result->SetTempExpression(0, getter->receiver()); | |
7756 result->SetTempExpression( | |
7757 1, | |
7758 new InstanceGetterNode( | |
7759 token_pos, | |
7760 new LoadLocalNode(token_pos, result->temp(0)), | |
7761 getter->field_name())); | |
7762 BinaryOpNode* add = new BinaryOpNode( | |
7763 token_pos, | |
7764 binary_op, | |
7765 new LoadLocalNode(token_pos, result->temp(1)), | |
7766 new LiteralNode(token_pos, Smi::ZoneHandle(Smi::New(1)))); | |
7767 InstanceSetterNode* store = new InstanceSetterNode( | |
7768 token_pos, | |
7769 new LoadLocalNode(token_pos, result->temp(0)), | |
7770 getter->field_name(), | |
7771 add); | |
7772 CommaNode* body = new CommaNode( | |
7773 token_pos, | |
7774 store, | |
7775 new LoadLocalNode(token_pos, result->temp(1))); // Result value. | |
7776 result->set_body(body); | |
7777 return result; | |
7778 } else { | |
7779 LetNode* result = new LetNode(token_pos, 1); | |
7780 result->SetTempExpression( | |
7781 0, | |
7782 new InstanceGetterNode( | |
7783 token_pos, | |
7784 getter->receiver(), | |
7785 getter->field_name())); | |
7786 BinaryOpNode* add = new BinaryOpNode( | |
7787 token_pos, | |
7788 binary_op, | |
7789 new LoadLocalNode(token_pos, result->temp(0)), | |
7790 new LiteralNode(token_pos, Smi::ZoneHandle(Smi::New(1)))); | |
7791 InstanceSetterNode* store = new InstanceSetterNode( | |
7792 token_pos, | |
7793 getter->receiver(), | |
7794 getter->field_name(), | |
7795 add); | |
7796 CommaNode* body = new CommaNode( | |
7797 token_pos, | |
7798 store, | |
7799 new LoadLocalNode(token_pos, result->temp(0))); // Result value. | |
7800 result->set_body(body); | |
7801 return result; | |
7802 } | |
7803 } | |
7773 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr); | 7804 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr); |
7774 const LocalVariable* temp = GetIncrementTempLocal(); | 7805 const LocalVariable* temp = GetIncrementTempLocal(); |
hausner
2013/05/28 17:00:47
Can this temporary local variable be handled with
Florian Schneider
2013/05/30 09:29:31
Yes, definitely. The plan is to replace it here as
| |
7775 AstNode* save = | 7806 AstNode* save = |
7776 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); | 7807 new StoreLocalNode(token_pos, temp, postfix_expr); |
7777 Token::Kind binary_op = | 7808 Token::Kind binary_op = |
7778 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 7809 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
7779 BinaryOpNode* add = new BinaryOpNode( | 7810 BinaryOpNode* add = new BinaryOpNode( |
7780 postfix_expr_pos, | 7811 token_pos, |
7781 binary_op, | 7812 binary_op, |
7782 save, | 7813 save, |
7783 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); | 7814 new LiteralNode(token_pos, Smi::ZoneHandle(Smi::New(1)))); |
7784 AstNode* store = CreateAssignmentNode(left_expr, add); | 7815 AstNode* store = CreateAssignmentNode(left_expr, add); |
7785 // The result is a pair of the (side effects of the) store followed by | 7816 // The result is a pair of the (side effects of the) store followed by |
7786 // the (value of the) initial value temp variable load. | 7817 // the (value of the) initial value temp variable load. |
7787 return new CommaNode( | 7818 return new CommaNode( |
7788 postfix_expr_pos, | 7819 token_pos, |
7789 store, | 7820 store, |
7790 new LoadLocalNode(postfix_expr_pos, temp)); | 7821 new LoadLocalNode(token_pos, temp)); |
7791 } | 7822 } |
7792 return postfix_expr; | 7823 return postfix_expr; |
7793 } | 7824 } |
7794 | 7825 |
7795 | 7826 |
7796 // Resolve the given type and its type arguments from the given scope class | 7827 // Resolve the given type and its type arguments from the given scope class |
7797 // according to the given type finalization mode. | 7828 // according to the given type finalization mode. |
7798 // If the given scope class is null, use the current library, but do not try to | 7829 // If the given scope class is null, use the current library, but do not try to |
7799 // resolve type parameters. | 7830 // resolve type parameters. |
7800 // Not all involved type classes may get resolved yet, but at least the type | 7831 // Not all involved type classes may get resolved yet, but at least the type |
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8855 } | 8886 } |
8856 factory_type_args = factory_type_args.Canonicalize(); | 8887 factory_type_args = factory_type_args.Canonicalize(); |
8857 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 8888 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
8858 if (element_list.length() == 0) { | 8889 if (element_list.length() == 0) { |
8859 // TODO(srdjan): Use Object::empty_array once issue 9871 has been fixed. | 8890 // TODO(srdjan): Use Object::empty_array once issue 9871 has been fixed. |
8860 Array& empty_array = Array::ZoneHandle(Object::empty_array().raw()); | 8891 Array& empty_array = Array::ZoneHandle(Object::empty_array().raw()); |
8861 LiteralNode* empty_array_literal = | 8892 LiteralNode* empty_array_literal = |
8862 new LiteralNode(TokenPos(), empty_array); | 8893 new LiteralNode(TokenPos(), empty_array); |
8863 factory_param->Add(empty_array_literal); | 8894 factory_param->Add(empty_array_literal); |
8864 } else { | 8895 } else { |
8865 const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos); | 8896 ArrayNode* list = new ArrayNode(TokenPos(), type, element_list); |
8866 ArrayNode* list = | |
8867 new ArrayNode(TokenPos(), type, temp_local, element_list); | |
8868 factory_param->Add(list); | 8897 factory_param->Add(list); |
8869 } | 8898 } |
8870 return CreateConstructorCallNode(literal_pos, | 8899 return CreateConstructorCallNode(literal_pos, |
8871 factory_type_args, | 8900 factory_type_args, |
8872 factory_method, | 8901 factory_method, |
8873 factory_param); | 8902 factory_param); |
8874 } | 8903 } |
8875 } | 8904 } |
8876 | 8905 |
8877 | 8906 |
8878 ConstructorCallNode* Parser::CreateConstructorCallNode( | 8907 ConstructorCallNode* Parser::CreateConstructorCallNode( |
8879 intptr_t token_pos, | 8908 intptr_t token_pos, |
8880 const AbstractTypeArguments& type_arguments, | 8909 const AbstractTypeArguments& type_arguments, |
8881 const Function& constructor, | 8910 const Function& constructor, |
8882 ArgumentListNode* arguments) { | 8911 ArgumentListNode* arguments) { |
8883 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 8912 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
8884 EnsureExpressionTemp(); | 8913 EnsureExpressionTemp(); |
8885 } | 8914 } |
8886 LocalVariable* allocated = | |
8887 CreateTempConstVariable(token_pos, "alloc"); | |
8888 return new ConstructorCallNode(token_pos, | 8915 return new ConstructorCallNode(token_pos, |
8889 type_arguments, | 8916 type_arguments, |
8890 constructor, | 8917 constructor, |
8891 arguments, | 8918 arguments); |
8892 allocated); | |
8893 } | 8919 } |
8894 | 8920 |
8895 | 8921 |
8896 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, | 8922 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, |
8897 bool is_const, | 8923 bool is_const, |
8898 AstNode* key, | 8924 AstNode* key, |
8899 AstNode* value) { | 8925 AstNode* value) { |
8900 if (is_const) { | 8926 if (is_const) { |
8901 ASSERT(key->IsLiteralNode()); | 8927 ASSERT(key->IsLiteralNode()); |
8902 ASSERT(key->AsLiteralNode()->literal().IsString()); | 8928 ASSERT(key->AsLiteralNode()->literal().IsString()); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9080 factory_type_args = factory_type.arguments(); | 9106 factory_type_args = factory_type.arguments(); |
9081 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 9107 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
9082 } | 9108 } |
9083 factory_type_args = factory_type_args.Canonicalize(); | 9109 factory_type_args = factory_type_args.Canonicalize(); |
9084 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 9110 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
9085 // The kv_pair array is temporary and of element type dynamic. It is passed | 9111 // The kv_pair array is temporary and of element type dynamic. It is passed |
9086 // to the factory to initialize a properly typed map. | 9112 // to the factory to initialize a properly typed map. |
9087 ArrayNode* kv_pairs = new ArrayNode( | 9113 ArrayNode* kv_pairs = new ArrayNode( |
9088 TokenPos(), | 9114 TokenPos(), |
9089 Type::ZoneHandle(Type::ArrayType()), | 9115 Type::ZoneHandle(Type::ArrayType()), |
9090 *BuildArrayTempLocal(type_pos), | |
9091 kv_pairs_list); | 9116 kv_pairs_list); |
9092 factory_param->Add(kv_pairs); | 9117 factory_param->Add(kv_pairs); |
9093 return CreateConstructorCallNode(literal_pos, | 9118 return CreateConstructorCallNode(literal_pos, |
9094 factory_type_args, | 9119 factory_type_args, |
9095 factory_method, | 9120 factory_method, |
9096 factory_param); | 9121 factory_param); |
9097 } | 9122 } |
9098 } | 9123 } |
9099 | 9124 |
9100 | 9125 |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9467 values_list.Add(expr); | 9492 values_list.Add(expr); |
9468 } | 9493 } |
9469 } | 9494 } |
9470 if (is_compiletime_const) { | 9495 if (is_compiletime_const) { |
9471 primary = new LiteralNode(literal_start, Interpolate(values_list)); | 9496 primary = new LiteralNode(literal_start, Interpolate(values_list)); |
9472 } else { | 9497 } else { |
9473 ArgumentListNode* interpolate_arg = new ArgumentListNode(TokenPos()); | 9498 ArgumentListNode* interpolate_arg = new ArgumentListNode(TokenPos()); |
9474 ArrayNode* values = new ArrayNode( | 9499 ArrayNode* values = new ArrayNode( |
9475 TokenPos(), | 9500 TokenPos(), |
9476 Type::ZoneHandle(Type::ArrayType()), | 9501 Type::ZoneHandle(Type::ArrayType()), |
9477 *BuildArrayTempLocal(TokenPos()), | |
9478 values_list); | 9502 values_list); |
9479 interpolate_arg->Add(values); | 9503 interpolate_arg->Add(values); |
9480 primary = MakeStaticCall(Symbols::StringBase(), | 9504 primary = MakeStaticCall(Symbols::StringBase(), |
9481 PrivateCoreLibName(Symbols::Interpolate()), | 9505 PrivateCoreLibName(Symbols::Interpolate()), |
9482 interpolate_arg); | 9506 interpolate_arg); |
9483 } | 9507 } |
9484 return primary; | 9508 return primary; |
9485 } | 9509 } |
9486 | 9510 |
9487 | 9511 |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9988 void Parser::SkipQualIdent() { | 10012 void Parser::SkipQualIdent() { |
9989 ASSERT(IsIdentifier()); | 10013 ASSERT(IsIdentifier()); |
9990 ConsumeToken(); | 10014 ConsumeToken(); |
9991 if (CurrentToken() == Token::kPERIOD) { | 10015 if (CurrentToken() == Token::kPERIOD) { |
9992 ConsumeToken(); // Consume the kPERIOD token. | 10016 ConsumeToken(); // Consume the kPERIOD token. |
9993 ExpectIdentifier("identifier expected after '.'"); | 10017 ExpectIdentifier("identifier expected after '.'"); |
9994 } | 10018 } |
9995 } | 10019 } |
9996 | 10020 |
9997 } // namespace dart | 10021 } // namespace dart |
OLD | NEW |