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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 115 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
116 ASSERT(node_sequence_ == NULL); | 116 ASSERT(node_sequence_ == NULL); |
117 ASSERT(node_sequence != NULL); | 117 ASSERT(node_sequence != NULL); |
118 node_sequence_ = node_sequence; | 118 node_sequence_ = node_sequence; |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const { | |
123 const int num_parameters = function().NumberOfParameters(); | |
124 LocalScope* scope = node_sequence()->scope(); | |
125 if (scope->num_variables() > num_parameters) { | |
126 LocalVariable* saved_args_desc_var = scope->VariableAt(num_parameters); | |
127 ASSERT(saved_args_desc_var != NULL); | |
128 // The scope of the formal parameters may also contain at this position | |
129 // an alias for the saved arguments descriptor variable of the enclosing | |
130 // function (check its scope owner) or an internal variable such as the | |
131 // expression temp variable or the saved entry context variable (check its | |
132 // name). | |
133 if ((saved_args_desc_var->owner() == scope) && | |
134 saved_args_desc_var->name().StartsWith( | |
135 String::Handle(Symbols::SavedArgDescVarPrefix()))) { | |
136 return saved_args_desc_var; | |
137 } | |
138 } | |
139 return NULL; | |
140 } | |
141 | |
142 | |
122 void ParsedFunction::AllocateVariables() { | 143 void ParsedFunction::AllocateVariables() { |
123 LocalScope* scope = node_sequence()->scope(); | 144 LocalScope* scope = node_sequence()->scope(); |
124 const int fixed_parameter_count = function().num_fixed_parameters(); | 145 const int fixed_parameter_count = function().num_fixed_parameters(); |
125 const int optional_parameter_count = function().num_optional_parameters(); | 146 const int optional_parameter_count = function().num_optional_parameters(); |
126 const int parameter_count = fixed_parameter_count + optional_parameter_count; | 147 int parameter_count = fixed_parameter_count + optional_parameter_count; |
127 const bool is_native_instance_closure = | 148 const bool is_native_instance_closure = |
128 function().is_native() && function().IsImplicitInstanceClosureFunction(); | 149 function().is_native() && function().IsImplicitInstanceClosureFunction(); |
129 // Compute start indices to parameters and locals, and the number of | 150 // Compute start indices to parameters and locals, and the number of |
130 // parameters to copy. | 151 // parameters to copy. |
131 if (optional_parameter_count == 0 && !is_native_instance_closure) { | 152 if ((optional_parameter_count == 0) && !is_native_instance_closure) { |
132 // Parameter i will be at fp[1 + parameter_count - i] and local variable | 153 // Parameter i will be at fp[1 + parameter_count - i] and local variable |
133 // j will be at fp[kFirstLocalSlotIndex - j]. | 154 // j will be at fp[kFirstLocalSlotIndex - j]. |
155 ASSERT(GetSavedArgumentsDescriptorVar() == NULL); | |
134 first_parameter_index_ = 1 + parameter_count; | 156 first_parameter_index_ = 1 + parameter_count; |
135 first_stack_local_index_ = kFirstLocalSlotIndex; | 157 first_stack_local_index_ = kFirstLocalSlotIndex; |
136 copied_parameter_count_ = 0; | 158 copied_parameter_count_ = 0; |
137 } else { | 159 } else { |
138 // Parameter i will be at fp[kFirstLocalSlotIndex - i] and local variable | 160 // Parameter i will be at fp[kFirstLocalSlotIndex - i] and local variable |
139 // j will be at fp[kFirstLocalSlotIndex - parameter_count - j]. | 161 // j will be at fp[kFirstLocalSlotIndex - parameter_count - j]. |
162 // The saved argument descriptor variable must be allocated similarly to | |
163 // a parameter, so that it gets both a frame slot and a context slot when | |
164 // captured. | |
165 if (GetSavedArgumentsDescriptorVar() != NULL) { | |
166 parameter_count += 1; | |
167 } | |
140 first_parameter_index_ = kFirstLocalSlotIndex; | 168 first_parameter_index_ = kFirstLocalSlotIndex; |
141 first_stack_local_index_ = first_parameter_index_ - parameter_count; | 169 first_stack_local_index_ = first_parameter_index_ - parameter_count; |
142 copied_parameter_count_ = parameter_count; | 170 copied_parameter_count_ = parameter_count; |
143 if (is_native_instance_closure) { | 171 if (is_native_instance_closure) { |
144 copied_parameter_count_ += 1; | 172 copied_parameter_count_ += 1; |
145 first_parameter_index_ -= 1; | 173 first_parameter_index_ -= 1; |
146 first_stack_local_index_ -= 1; | 174 first_stack_local_index_ -= 1; |
147 } | 175 } |
148 } | 176 } |
149 | 177 |
150 // Allocate parameters and local variables, either in the local frame or | 178 // Allocate parameters and local variables, either in the local frame or |
151 // in the context(s). | 179 // in the context(s). |
152 LocalScope* context_owner = NULL; // No context needed yet. | 180 LocalScope* context_owner = NULL; // No context needed yet. |
153 int next_free_frame_index = | 181 int next_free_frame_index = |
154 scope->AllocateVariables(first_parameter_index_, | 182 scope->AllocateVariables(first_parameter_index_, |
155 parameter_count, | 183 parameter_count, |
156 first_stack_local_index_, | 184 first_stack_local_index_, |
157 scope, | 185 scope, |
158 &context_owner); | 186 &context_owner); |
159 | 187 |
160 // If this function is not a closure function and if it contains captured | 188 // If this function is not a closure function and if it contains captured |
161 // variables, the context needs to be saved on entry and restored on exit. | 189 // variables, the context needs to be saved on entry and restored on exit. |
162 // Add and allocate a local variable to this purpose. | 190 // Add and allocate a local variable to this purpose. |
163 if ((context_owner != NULL) && !function().IsClosureFunction()) { | 191 if ((context_owner != NULL) && !function().IsClosureFunction()) { |
164 const String& context_var_name = String::ZoneHandle( | 192 const String& context_var_name = |
165 Symbols::New(LocalVariable::kSavedContextVarName)); | 193 String::ZoneHandle(Symbols::SavedEntryContextVar()); |
166 LocalVariable* context_var = | 194 LocalVariable* context_var = |
167 new LocalVariable(function().token_pos(), | 195 new LocalVariable(function().token_pos(), |
168 context_var_name, | 196 context_var_name, |
169 Type::ZoneHandle(Type::DynamicType())); | 197 Type::ZoneHandle(Type::DynamicType())); |
170 context_var->set_index(next_free_frame_index--); | 198 context_var->set_index(next_free_frame_index--); |
171 scope->AddVariable(context_var); | 199 scope->AddVariable(context_var); |
172 set_saved_context_var(context_var); | 200 set_saved_context_var(context_var); |
173 } | 201 } |
174 | 202 |
175 // Frame indices are relative to the frame pointer and are decreasing. | 203 // Frame indices are relative to the frame pointer and are decreasing. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 token_kind_(Token::kILLEGAL), | 282 token_kind_(Token::kILLEGAL), |
255 current_block_(NULL), | 283 current_block_(NULL), |
256 is_top_level_(false), | 284 is_top_level_(false), |
257 current_member_(NULL), | 285 current_member_(NULL), |
258 allow_function_literals_(true), | 286 allow_function_literals_(true), |
259 current_function_(function), | 287 current_function_(function), |
260 innermost_function_(Function::Handle(function.raw())), | 288 innermost_function_(Function::Handle(function.raw())), |
261 current_class_(Class::Handle(current_function_.Owner())), | 289 current_class_(Class::Handle(current_function_.Owner())), |
262 library_(Library::Handle(current_class_.library())), | 290 library_(Library::Handle(current_class_.library())), |
263 try_blocks_list_(NULL), | 291 try_blocks_list_(NULL), |
264 expression_temp_(NULL) { | 292 expression_temp_(NULL) { |
265 ASSERT(tokens_iterator_.IsValid()); | 293 ASSERT(tokens_iterator_.IsValid()); |
266 ASSERT(!function.IsNull()); | 294 ASSERT(!function.IsNull()); |
267 if (FLAG_enable_type_checks) { | 295 if (FLAG_enable_type_checks) { |
268 EnsureExpressionTemp(); | 296 EnsureExpressionTemp(); |
269 } | 297 } |
270 } | 298 } |
271 | 299 |
272 | 300 |
273 bool Parser::SetAllowFunctionLiterals(bool value) { | 301 bool Parser::SetAllowFunctionLiterals(bool value) { |
274 bool current_value = allow_function_literals_; | 302 bool current_value = allow_function_literals_; |
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1126 } | 1154 } |
1127 | 1155 |
1128 | 1156 |
1129 void Parser::ParseFormalParameterList(bool allow_explicit_default_values, | 1157 void Parser::ParseFormalParameterList(bool allow_explicit_default_values, |
1130 ParamList* params) { | 1158 ParamList* params) { |
1131 TRACE_PARSER("ParseFormalParameterList"); | 1159 TRACE_PARSER("ParseFormalParameterList"); |
1132 ASSERT(CurrentToken() == Token::kLPAREN); | 1160 ASSERT(CurrentToken() == Token::kLPAREN); |
1133 | 1161 |
1134 if (LookaheadToken(1) != Token::kRPAREN) { | 1162 if (LookaheadToken(1) != Token::kRPAREN) { |
1135 // Parse positional parameters. | 1163 // Parse positional parameters. |
1136 ParseFormalParameters(allow_explicit_default_values, | 1164 ParseFormalParameters(allow_explicit_default_values, params); |
1137 params); | |
1138 if (params->has_named_optional_parameters) { | 1165 if (params->has_named_optional_parameters) { |
1139 // Parse named optional parameters. | 1166 // Parse named optional parameters. |
1140 ParseFormalParameters(allow_explicit_default_values, | 1167 ParseFormalParameters(allow_explicit_default_values, params); |
1141 params); | |
1142 if (CurrentToken() != Token::kRBRACK) { | 1168 if (CurrentToken() != Token::kRBRACK) { |
1143 ErrorMsg("',' or ']' expected"); | 1169 ErrorMsg("',' or ']' expected"); |
1144 } | 1170 } |
1145 ExpectToken(Token::kRBRACK); | 1171 ExpectToken(Token::kRBRACK); |
1146 } | 1172 } |
1147 if ((CurrentToken() != Token::kRPAREN) && | 1173 if ((CurrentToken() != Token::kRPAREN) && |
1148 !params->has_named_optional_parameters) { | 1174 !params->has_named_optional_parameters) { |
1149 ErrorMsg("',' or ')' expected"); | 1175 ErrorMsg("',' or ')' expected"); |
1150 } | 1176 } |
1151 } else { | 1177 } else { |
(...skipping 6197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7349 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 7375 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
7350 if (current_block_ == NULL) { | 7376 if (current_block_ == NULL) { |
7351 return NULL; | 7377 return NULL; |
7352 } | 7378 } |
7353 // A found name is treated as accessed and possibly marked as captured. | 7379 // A found name is treated as accessed and possibly marked as captured. |
7354 const bool kTestOnly = false; | 7380 const bool kTestOnly = false; |
7355 return current_block_->scope->LookupVariable(ident, kTestOnly); | 7381 return current_block_->scope->LookupVariable(ident, kTestOnly); |
7356 } | 7382 } |
7357 | 7383 |
7358 | 7384 |
7385 // Returns true if ident resolves to a formal parameter of the current function | |
7386 // or of one of its enclosing functions. | |
7387 // Make sure not to capture the formal parameter, since it is not accessed. | |
7388 bool Parser::IsFormalParameter(const String& ident, | |
7389 Function* owner_function, | |
7390 LocalScope** owner_scope, | |
7391 intptr_t* local_index) { | |
7392 if (current_block_ == NULL) { | |
7393 return false; | |
7394 } | |
7395 if (ident.Equals(String::Handle(Symbols::This()))) { | |
7396 // 'this' is not a formal parameter. | |
7397 return false; | |
7398 } | |
7399 // Since an argument definition test does not use the value of the formal | |
7400 // parameter, there is no reason to capture it. | |
7401 const bool kTestOnly = true; // No capturing. | |
7402 LocalVariable* local = | |
7403 current_block_->scope->LookupVariable(ident, kTestOnly); | |
7404 if (local == NULL) { | |
7405 if (!current_function().IsLocalFunction()) { | |
7406 // We are not generating code for a local function, so all locals, | |
7407 // captured or not, are in scope. However, 'ident' was not found, so it | |
7408 // does not exist. | |
7409 return false; | |
7410 } | |
7411 // The formal parameter may belong to an enclosing function and may not have | |
7412 // been captured, so it was not included in the context scope and it cannot | |
7413 // be found by LookupVariable. | |
7414 // 'ident' necessarily refers to the formal parameter of one of the | |
7415 // enclosing functions, or a compile error would have prevented the | |
7416 // outermost enclosing function to be executed and we would not be compiling | |
7417 // this local function. | |
7418 // Therefore, look for ident directly in the formal parameter lists of the | |
7419 // enclosing functions. | |
7420 // There is no need to return the owner_scope, since the caller will not | |
7421 // create the saved_arguments_descriptor variable, which already exists. | |
7422 Function& function = Function::Handle(innermost_function().raw()); | |
7423 String& param_name = String::Handle(); | |
7424 do { | |
7425 const int num_parameters = function.NumberOfParameters(); | |
7426 for (intptr_t i = 0; i < num_parameters; i++) { | |
7427 param_name = function.ParameterNameAt(i); | |
7428 if (ident.Equals(param_name)) { | |
7429 *owner_function = function.raw(); | |
7430 *owner_scope = NULL; | |
7431 *local_index = i; | |
7432 return true; | |
7433 } | |
7434 } | |
7435 function = function.parent_function(); | |
7436 } while (!function.IsNull()); | |
7437 UNREACHABLE(); | |
hausner
2012/08/31 00:34:55
Is this really unreachable? What if the name refer
regis
2012/08/31 01:36:18
Indeed, you missed the comment on line 7414 explai
| |
7438 } | |
7439 // Verify that local is a formal parameter of the current function or of one | |
7440 // of its enclosing functions. | |
7441 // Note that scopes are not yet associated to functions. | |
7442 Function& function = Function::Handle(innermost_function().raw()); | |
7443 LocalScope* scope = current_block_->scope; | |
7444 while (scope != NULL) { | |
7445 ASSERT(!function.IsNull()); | |
7446 // Find the top scope for this function level. | |
7447 while ((scope->parent() != NULL) && | |
7448 (scope->parent()->function_level() == scope->function_level())) { | |
7449 scope = scope->parent(); | |
7450 } | |
7451 if (scope == local->owner()) { | |
7452 // Scope contains 'local' and the formal parameters of 'function'. | |
7453 const int num_parameters = function.NumberOfParameters(); | |
7454 for (intptr_t i = 0; i < num_parameters; i++) { | |
7455 if (scope->VariableAt(i) == local) { | |
7456 *owner_function = function.raw(); | |
7457 *owner_scope = scope; | |
7458 *local_index = i; | |
7459 return true; | |
7460 } | |
7461 } | |
7462 // The variable 'local' is not a formal parameter. | |
7463 return false; | |
7464 } | |
7465 scope = scope->parent(); | |
7466 function = function.parent_function(); | |
7467 } | |
7468 // The variable 'local' does not belong to a function top scope. | |
7469 return false; | |
7470 } | |
7471 | |
7472 | |
7359 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 7473 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
7360 const String& field_name) { | 7474 const String& field_name) { |
7361 // Fields are not accessible from a static function, except from a | 7475 // Fields are not accessible from a static function, except from a |
7362 // constructor, which is considered as non-static by the compiler. | 7476 // constructor, which is considered as non-static by the compiler. |
7363 if (current_function().is_static()) { | 7477 if (current_function().is_static()) { |
7364 ErrorMsg(field_pos, | 7478 ErrorMsg(field_pos, |
7365 "cannot access instance field '%s' from a static function", | 7479 "cannot access instance field '%s' from a static function", |
7366 field_name.ToCString()); | 7480 field_name.ToCString()); |
7367 } | 7481 } |
7368 } | 7482 } |
(...skipping 1452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8821 ConsumeToken(); | 8935 ConsumeToken(); |
8822 } | 8936 } |
8823 } | 8937 } |
8824 // A string literal always ends with a kSTRING token. | 8938 // A string literal always ends with a kSTRING token. |
8825 ASSERT(CurrentToken() == Token::kSTRING); | 8939 ASSERT(CurrentToken() == Token::kSTRING); |
8826 } | 8940 } |
8827 return &result; | 8941 return &result; |
8828 } | 8942 } |
8829 | 8943 |
8830 | 8944 |
8945 AstNode* Parser::ParseArgumentDefinitionTest() { | |
8946 const intptr_t test_pos = TokenPos(); | |
8947 ConsumeToken(); | |
8948 const intptr_t ident_pos = TokenPos(); | |
8949 String* ident = ExpectIdentifier("parameter name expected"); | |
8950 Function& owner_function = Function::Handle(); | |
8951 LocalScope* owner_scope; | |
8952 intptr_t param_index; | |
8953 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, ¶m_index)) { | |
8954 ErrorMsg(ident_pos, "formal parameter name expected"); | |
8955 } | |
8956 if (param_index < owner_function.num_fixed_parameters()) { | |
8957 // The formal parameter is not optional, therefore the corresponding | |
8958 // argument is always passed and defined. | |
8959 return new LiteralNode(test_pos, Bool::ZoneHandle(Bool::True())); | |
8960 } | |
8961 char name[64]; | |
8962 OS::SNPrint(name, 64, "%s_%d", | |
8963 Symbols::Name(Symbols::kSavedArgDescVarPrefix), | |
8964 owner_function.token_pos()); | |
8965 const String& saved_args_desc_name = String::ZoneHandle(Symbols::New(name)); | |
8966 LocalVariable* saved_args_desc_var = LookupLocalScope(saved_args_desc_name); | |
8967 if (saved_args_desc_var == NULL) { | |
8968 ASSERT(owner_scope != NULL); | |
8969 ASSERT(owner_function.raw() == current_function().raw()); | |
8970 // We currently generate code for 'owner_function', otherwise the variable | |
8971 // would have been created when compiling the enclosing function of the | |
8972 // currently being compiled local function. | |
8973 saved_args_desc_var = | |
8974 new LocalVariable(owner_function.token_pos(), | |
8975 saved_args_desc_name, | |
8976 Type::ZoneHandle(Type::ListInterface())); | |
8977 saved_args_desc_var->set_is_final(); | |
8978 // The saved arguments descriptor variable must be added just after the | |
8979 // formal parameters. This simplifies the 2-step saving of a captured | |
8980 // arguments descriptor. | |
8981 // At this time, the owner scope should only contain formal parameters. | |
8982 ASSERT(owner_scope->num_variables() == owner_function.NumberOfParameters()); | |
8983 bool success = owner_scope->AddVariable(saved_args_desc_var); | |
8984 ASSERT(success); | |
8985 // Capture the saved argument descriptor variable if necessary. | |
8986 if (current_function().raw() != innermost_function().raw()) { | |
8987 LocalVariable* local = LookupLocalScope(saved_args_desc_name); | |
8988 ASSERT(local == saved_args_desc_var); | |
8989 ASSERT(local->is_captured()); | |
8990 } | |
8991 } else { | |
8992 // If we currently generate code for a local function of the owner function, | |
8993 // the saved arguments descriptor variable must have been captured by the | |
8994 // above lookup. | |
8995 ASSERT((owner_function.raw() == current_function().raw()) || | |
8996 saved_args_desc_var->is_captured()); | |
8997 } | |
8998 const String& param_name = String::ZoneHandle(Symbols::New(*ident)); | |
8999 return new ArgumentDefinitionTestNode( | |
9000 test_pos, param_index, param_name, saved_args_desc_var); | |
9001 } | |
9002 | |
9003 | |
8831 AstNode* Parser::ParsePrimary() { | 9004 AstNode* Parser::ParsePrimary() { |
8832 TRACE_PARSER("ParsePrimary"); | 9005 TRACE_PARSER("ParsePrimary"); |
8833 ASSERT(!is_top_level_); | 9006 ASSERT(!is_top_level_); |
8834 AstNode* primary = NULL; | 9007 AstNode* primary = NULL; |
8835 if (IsFunctionLiteral()) { | 9008 if (IsFunctionLiteral()) { |
8836 // The name of a literal function is visible from inside the function, but | 9009 // The name of a literal function is visible from inside the function, but |
8837 // must not collide with names in the scope declaring the literal. | 9010 // must not collide with names in the scope declaring the literal. |
8838 OpenBlock(); | 9011 OpenBlock(); |
8839 primary = ParseFunctionStatement(true); | 9012 primary = ParseFunctionStatement(true); |
8840 CloseBlock(); | 9013 CloseBlock(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8940 primary = ParseSuperCall(ident); | 9113 primary = ParseSuperCall(ident); |
8941 } else { | 9114 } else { |
8942 primary = ParseSuperFieldAccess(ident); | 9115 primary = ParseSuperFieldAccess(ident); |
8943 } | 9116 } |
8944 } else if ((CurrentToken() == Token::kLBRACK) || | 9117 } else if ((CurrentToken() == Token::kLBRACK) || |
8945 Token::CanBeOverloaded(CurrentToken())) { | 9118 Token::CanBeOverloaded(CurrentToken())) { |
8946 primary = ParseSuperOperator(); | 9119 primary = ParseSuperOperator(); |
8947 } else { | 9120 } else { |
8948 ErrorMsg("illegal super call"); | 9121 ErrorMsg("illegal super call"); |
8949 } | 9122 } |
9123 } else if (CurrentToken() == Token::kCONDITIONAL) { | |
9124 primary = ParseArgumentDefinitionTest(); | |
8950 } else { | 9125 } else { |
8951 UnexpectedToken(); | 9126 UnexpectedToken(); |
8952 } | 9127 } |
8953 return primary; | 9128 return primary; |
8954 } | 9129 } |
8955 | 9130 |
8956 | 9131 |
8957 // Evaluate expression in expr and return the value. The expression must | 9132 // Evaluate expression in expr and return the value. The expression must |
8958 // be a compile time constant. | 9133 // be a compile time constant. |
8959 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { | 9134 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9240 void Parser::SkipQualIdent() { | 9415 void Parser::SkipQualIdent() { |
9241 ASSERT(IsIdentifier()); | 9416 ASSERT(IsIdentifier()); |
9242 ConsumeToken(); | 9417 ConsumeToken(); |
9243 if (CurrentToken() == Token::kPERIOD) { | 9418 if (CurrentToken() == Token::kPERIOD) { |
9244 ConsumeToken(); // Consume the kPERIOD token. | 9419 ConsumeToken(); // Consume the kPERIOD token. |
9245 ExpectIdentifier("identifier expected after '.'"); | 9420 ExpectIdentifier("identifier expected after '.'"); |
9246 } | 9421 } |
9247 } | 9422 } |
9248 | 9423 |
9249 } // namespace dart | 9424 } // namespace dart |
OLD | NEW |