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

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

Issue 260713008: Add support for javascript incompatibility warnings. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
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/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 case RawFunction::kRegularFunction: 803 case RawFunction::kRegularFunction:
804 case RawFunction::kClosureFunction: 804 case RawFunction::kClosureFunction:
805 case RawFunction::kGetterFunction: 805 case RawFunction::kGetterFunction:
806 case RawFunction::kSetterFunction: 806 case RawFunction::kSetterFunction:
807 case RawFunction::kConstructor: 807 case RawFunction::kConstructor:
808 // The call to a redirecting factory is redirected. 808 // The call to a redirecting factory is redirected.
809 ASSERT(!func.IsRedirectingFactory()); 809 ASSERT(!func.IsRedirectingFactory());
810 if (!func.IsImplicitConstructor()) { 810 if (!func.IsImplicitConstructor()) {
811 parser.SkipFunctionPreamble(); 811 parser.SkipFunctionPreamble();
812 } 812 }
813 node_sequence = parser.ParseFunc(func, default_parameter_values); 813 node_sequence = parser.ParseFunc(func, &default_parameter_values);
814 break; 814 break;
815 case RawFunction::kImplicitGetter: 815 case RawFunction::kImplicitGetter:
816 ASSERT(!func.is_static()); 816 ASSERT(!func.is_static());
817 node_sequence = parser.ParseInstanceGetter(func); 817 node_sequence = parser.ParseInstanceGetter(func);
818 break; 818 break;
819 case RawFunction::kImplicitSetter: 819 case RawFunction::kImplicitSetter:
820 ASSERT(!func.is_static()); 820 ASSERT(!func.is_static());
821 node_sequence = parser.ParseInstanceSetter(func); 821 node_sequence = parser.ParseInstanceSetter(func);
822 break; 822 break;
823 case RawFunction::kImplicitStaticFinalGetter: 823 case RawFunction::kImplicitStaticFinalGetter:
824 node_sequence = parser.ParseStaticFinalGetter(func); 824 node_sequence = parser.ParseStaticFinalGetter(func);
825 CompilerStats::num_implicit_final_getters++; 825 CompilerStats::num_implicit_final_getters++;
826 break; 826 break;
827 case RawFunction::kStaticInitializer: 827 case RawFunction::kStaticInitializer:
828 node_sequence = parser.ParseStaticInitializer(func); 828 node_sequence = parser.ParseStaticInitializer(func);
829 CompilerStats::num_static_initializer_funcs++; 829 CompilerStats::num_static_initializer_funcs++;
830 break; 830 break;
831 case RawFunction::kMethodExtractor: 831 case RawFunction::kMethodExtractor:
832 node_sequence = parser.ParseMethodExtractor(func); 832 node_sequence = parser.ParseMethodExtractor(func);
833 break; 833 break;
834 case RawFunction::kNoSuchMethodDispatcher: 834 case RawFunction::kNoSuchMethodDispatcher:
835 node_sequence = 835 node_sequence =
836 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); 836 parser.ParseNoSuchMethodDispatcher(func, &default_parameter_values);
837 break; 837 break;
838 case RawFunction::kInvokeFieldDispatcher: 838 case RawFunction::kInvokeFieldDispatcher:
839 node_sequence = 839 node_sequence =
840 parser.ParseInvokeFieldDispatcher(func, default_parameter_values); 840 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values);
841 break; 841 break;
842 default: 842 default:
843 UNREACHABLE(); 843 UNREACHABLE();
844 } 844 }
845 845
846 if (!HasReturnNode(node_sequence)) { 846 if (!HasReturnNode(node_sequence)) {
847 // Add implicit return node. 847 // Add implicit return node.
848 node_sequence->Add(new ReturnNode(func.end_token_pos())); 848 node_sequence->Add(new ReturnNode(func.end_token_pos()));
849 } 849 }
850 if (parsed_function->has_expression_temp_var()) { 850 if (parsed_function->has_expression_temp_var()) {
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 NULL); 1294 NULL);
1295 1295
1296 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); 1296 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure);
1297 current_block_->statements->Add(return_node); 1297 current_block_->statements->Add(return_node);
1298 return CloseBlock(); 1298 return CloseBlock();
1299 } 1299 }
1300 1300
1301 1301
1302 void Parser::BuildDispatcherScope(const Function& func, 1302 void Parser::BuildDispatcherScope(const Function& func,
1303 const ArgumentsDescriptor& desc, 1303 const ArgumentsDescriptor& desc,
1304 Array& default_values) { 1304 Array* default_values) {
1305 ParamList params; 1305 ParamList params;
1306 // Receiver first. 1306 // Receiver first.
1307 intptr_t token_pos = func.token_pos(); 1307 intptr_t token_pos = func.token_pos();
1308 params.AddReceiver(ReceiverType(current_class()), token_pos); 1308 params.AddReceiver(ReceiverType(current_class()), token_pos);
1309 // Remaining positional parameters. 1309 // Remaining positional parameters.
1310 intptr_t i = 1; 1310 intptr_t i = 1;
1311 for (; i < desc.PositionalCount(); ++i) { 1311 for (; i < desc.PositionalCount(); ++i) {
1312 ParamDesc p; 1312 ParamDesc p;
1313 char name[64]; 1313 char name[64];
1314 OS::SNPrint(name, 64, ":p%" Pd, i); 1314 OS::SNPrint(name, 64, ":p%" Pd, i);
(...skipping 18 matching lines...) Expand all
1333 ASSERT(desc.NamedCount() == params.num_optional_parameters); 1333 ASSERT(desc.NamedCount() == params.num_optional_parameters);
1334 1334
1335 SetupDefaultsForOptionalParams(&params, default_values); 1335 SetupDefaultsForOptionalParams(&params, default_values);
1336 1336
1337 // Build local scope for function and populate with the formal parameters. 1337 // Build local scope for function and populate with the formal parameters.
1338 OpenFunctionBlock(func); 1338 OpenFunctionBlock(func);
1339 AddFormalParamsToScope(&params, current_block_->scope); 1339 AddFormalParamsToScope(&params, current_block_->scope);
1340 } 1340 }
1341 1341
1342 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, 1342 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func,
1343 Array& default_values) { 1343 Array* default_values) {
1344 TRACE_PARSER("ParseNoSuchMethodDispatcher"); 1344 TRACE_PARSER("ParseNoSuchMethodDispatcher");
1345 1345
1346 ASSERT(func.IsNoSuchMethodDispatcher()); 1346 ASSERT(func.IsNoSuchMethodDispatcher());
1347 intptr_t token_pos = func.token_pos(); 1347 intptr_t token_pos = func.token_pos();
1348 ASSERT(func.token_pos() == 0); 1348 ASSERT(func.token_pos() == 0);
1349 ASSERT(current_class().raw() == func.Owner()); 1349 ASSERT(current_class().raw() == func.Owner());
1350 1350
1351 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc())); 1351 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc()));
1352 ASSERT(desc.Count() > 0); 1352 ASSERT(desc.Count() > 0);
1353 1353
(...skipping 24 matching lines...) Expand all
1378 StaticCallNode* call = 1378 StaticCallNode* call =
1379 new StaticCallNode(token_pos, no_such_method, arguments); 1379 new StaticCallNode(token_pos, no_such_method, arguments);
1380 1380
1381 ReturnNode* return_node = new ReturnNode(token_pos, call); 1381 ReturnNode* return_node = new ReturnNode(token_pos, call);
1382 current_block_->statements->Add(return_node); 1382 current_block_->statements->Add(return_node);
1383 return CloseBlock(); 1383 return CloseBlock();
1384 } 1384 }
1385 1385
1386 1386
1387 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, 1387 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func,
1388 Array& default_values) { 1388 Array* default_values) {
1389 TRACE_PARSER("ParseInvokeFieldDispatcher"); 1389 TRACE_PARSER("ParseInvokeFieldDispatcher");
1390 1390
1391 ASSERT(func.IsInvokeFieldDispatcher()); 1391 ASSERT(func.IsInvokeFieldDispatcher());
1392 intptr_t token_pos = func.token_pos(); 1392 intptr_t token_pos = func.token_pos();
1393 ASSERT(func.token_pos() == 0); 1393 ASSERT(func.token_pos() == 0);
1394 ASSERT(current_class().raw() == func.Owner()); 1394 ASSERT(current_class().raw() == func.Owner());
1395 1395
1396 const Array& args_desc = Array::Handle(func.saved_args_desc()); 1396 const Array& args_desc = Array::Handle(func.saved_args_desc());
1397 ArgumentsDescriptor desc(args_desc); 1397 ArgumentsDescriptor desc(args_desc);
1398 ASSERT(desc.Count() > 0); 1398 ASSERT(desc.Count() > 0);
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2554 } 2554 }
2555 ASSERT(!unregister_pending_function_); 2555 ASSERT(!unregister_pending_function_);
2556 pending_functions.Add(current_function()); 2556 pending_functions.Add(current_function());
2557 unregister_pending_function_ = true; 2557 unregister_pending_function_ = true;
2558 } 2558 }
2559 2559
2560 2560
2561 // Parser is at the opening parenthesis of the formal parameter declaration 2561 // Parser is at the opening parenthesis of the formal parameter declaration
2562 // of function. Parse the formal parameters, initializers and code. 2562 // of function. Parse the formal parameters, initializers and code.
2563 SequenceNode* Parser::ParseConstructor(const Function& func, 2563 SequenceNode* Parser::ParseConstructor(const Function& func,
2564 Array& default_parameter_values) { 2564 Array* default_parameter_values) {
2565 TRACE_PARSER("ParseConstructor"); 2565 TRACE_PARSER("ParseConstructor");
2566 ASSERT(func.IsConstructor()); 2566 ASSERT(func.IsConstructor());
2567 ASSERT(!func.IsFactory()); 2567 ASSERT(!func.IsFactory());
2568 ASSERT(!func.is_static()); 2568 ASSERT(!func.is_static());
2569 ASSERT(!func.IsLocalFunction()); 2569 ASSERT(!func.IsLocalFunction());
2570 const Class& cls = Class::Handle(func.Owner()); 2570 const Class& cls = Class::Handle(func.Owner());
2571 ASSERT(!cls.IsNull()); 2571 ASSERT(!cls.IsNull());
2572 2572
2573 CheckRecursiveInvocation(); 2573 CheckRecursiveInvocation();
2574 2574
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2846 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); 2846 current_block_->statements->Add(new ReturnNode(func.end_token_pos()));
2847 SequenceNode* statements = CloseBlock(); 2847 SequenceNode* statements = CloseBlock();
2848 return statements; 2848 return statements;
2849 } 2849 }
2850 2850
2851 2851
2852 // Parser is at the opening parenthesis of the formal parameter 2852 // Parser is at the opening parenthesis of the formal parameter
2853 // declaration of the function or constructor. 2853 // declaration of the function or constructor.
2854 // Parse the formal parameters and code. 2854 // Parse the formal parameters and code.
2855 SequenceNode* Parser::ParseFunc(const Function& func, 2855 SequenceNode* Parser::ParseFunc(const Function& func,
2856 Array& default_parameter_values) { 2856 Array* default_parameter_values) {
2857 TRACE_PARSER("ParseFunc"); 2857 TRACE_PARSER("ParseFunc");
2858 Function& saved_innermost_function = 2858 Function& saved_innermost_function =
2859 Function::Handle(innermost_function().raw()); 2859 Function::Handle(innermost_function().raw());
2860 innermost_function_ = func.raw(); 2860 innermost_function_ = func.raw();
2861 2861
2862 // Save current try index. Try index starts at zero for each function. 2862 // Save current try index. Try index starts at zero for each function.
2863 intptr_t saved_try_index = last_used_try_index_; 2863 intptr_t saved_try_index = last_used_try_index_;
2864 last_used_try_index_ = 0; 2864 last_used_try_index_ = 0;
2865 2865
2866 // TODO(12455) : Need better validation mechanism. 2866 // TODO(12455) : Need better validation mechanism.
(...skipping 2458 matching lines...) Expand 10 before | Expand all | Expand 10 after
5325 current_block_->scope->set_begin_token_pos(statements->token_pos()); 5325 current_block_->scope->set_begin_token_pos(statements->token_pos());
5326 current_block_->scope->set_end_token_pos(TokenPos()); 5326 current_block_->scope->set_end_token_pos(TokenPos());
5327 } 5327 }
5328 current_block_ = current_block_->parent; 5328 current_block_ = current_block_->parent;
5329 return statements; 5329 return statements;
5330 } 5330 }
5331 5331
5332 5332
5333 // Set up default values for all optional parameters to the function. 5333 // Set up default values for all optional parameters to the function.
5334 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, 5334 void Parser::SetupDefaultsForOptionalParams(const ParamList* params,
5335 Array& default_values) { 5335 Array* default_values) {
5336 if (params->num_optional_parameters > 0) { 5336 if (params->num_optional_parameters > 0) {
5337 // Build array of default parameter values. 5337 // Build array of default parameter values.
5338 ParamDesc* param = 5338 ParamDesc* param =
5339 params->parameters->data() + params->num_fixed_parameters; 5339 params->parameters->data() + params->num_fixed_parameters;
5340 default_values = Array::New(params->num_optional_parameters); 5340 *default_values = Array::New(params->num_optional_parameters);
5341 for (int i = 0; i < params->num_optional_parameters; i++) { 5341 for (int i = 0; i < params->num_optional_parameters; i++) {
5342 ASSERT(param->default_value != NULL); 5342 ASSERT(param->default_value != NULL);
5343 default_values.SetAt(i, *param->default_value); 5343 default_values->SetAt(i, *param->default_value);
5344 param++; 5344 param++;
5345 } 5345 }
5346 } 5346 }
5347 } 5347 }
5348 5348
5349 5349
5350 // Populate the parameter type array and parameter name array of the function 5350 // Populate the parameter type array and parameter name array of the function
5351 // with the formal parameter types and names. 5351 // with the formal parameter types and names.
5352 void Parser::AddFormalParamsToFunction(const ParamList* params, 5352 void Parser::AddFormalParamsToFunction(const ParamList* params,
5353 const Function& func) { 5353 const Function& func) {
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
5759 ErrorMsg(function_pos, 5759 ErrorMsg(function_pos,
5760 "'%s' from outer scope has already been used, cannot redefine", 5760 "'%s' from outer scope has already been used, cannot redefine",
5761 function_variable->name().ToCString()); 5761 function_variable->name().ToCString());
5762 } 5762 }
5763 } 5763 }
5764 } 5764 }
5765 5765
5766 // Parse the local function. 5766 // Parse the local function.
5767 Array& default_parameter_values = Array::Handle(); 5767 Array& default_parameter_values = Array::Handle();
5768 SequenceNode* statements = Parser::ParseFunc(function, 5768 SequenceNode* statements = Parser::ParseFunc(function,
5769 default_parameter_values); 5769 &default_parameter_values);
5770 5770
5771 // Now that the local function has formal parameters, lookup the signature 5771 // Now that the local function has formal parameters, lookup the signature
5772 // class in the current library (but not in its imports) and only create a new 5772 // class in the current library (but not in its imports) and only create a new
5773 // canonical signature class if it does not exist yet. 5773 // canonical signature class if it does not exist yet.
5774 const String& signature = String::Handle(function.Signature()); 5774 const String& signature = String::Handle(function.Signature());
5775 Class& signature_class = Class::ZoneHandle(); 5775 Class& signature_class = Class::ZoneHandle();
5776 if (!is_new_closure) { 5776 if (!is_new_closure) {
5777 signature_class = function.signature_class(); 5777 signature_class = function.signature_class();
5778 } 5778 }
5779 if (signature_class.IsNull()) { 5779 if (signature_class.IsNull()) {
(...skipping 3210 matching lines...) Expand 10 before | Expand all | Expand 10 after
8990 // not optimizable. 8990 // not optimizable.
8991 current_function().SetIsOptimizable(false); 8991 current_function().SetIsOptimizable(false);
8992 field.set_value(Object::null_instance()); 8992 field.set_value(Object::null_instance());
8993 // It is a compile-time error if evaluation of a compile-time constant 8993 // It is a compile-time error if evaluation of a compile-time constant
8994 // would raise an exception. 8994 // would raise an exception.
8995 AppendErrorMsg(error, field_ref_pos, 8995 AppendErrorMsg(error, field_ref_pos,
8996 "error initializing const field '%s'", 8996 "error initializing const field '%s'",
8997 String::Handle(field.name()).ToCString()); 8997 String::Handle(field.name()).ToCString());
8998 } else { 8998 } else {
8999 isolate()->long_jump_base()->Jump(1, error); 8999 isolate()->long_jump_base()->Jump(1, error);
9000 UNREACHABLE();
9000 } 9001 }
9001 } 9002 }
9002 ASSERT(const_value.IsNull() || const_value.IsInstance()); 9003 ASSERT(const_value.IsNull() || const_value.IsInstance());
9003 Instance& instance = Instance::Handle(); 9004 Instance& instance = Instance::Handle();
9004 instance ^= const_value.raw(); 9005 instance ^= const_value.raw();
9005 instance = TryCanonicalize(instance, field_ref_pos); 9006 instance = TryCanonicalize(instance, field_ref_pos);
9006 field.set_value(instance); 9007 field.set_value(instance);
9007 return NULL; // Constant 9008 return NULL; // Constant
9008 } else { 9009 } else {
9009 return new StaticGetterNode(field_ref_pos, 9010 return new StaticGetterNode(field_ref_pos,
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
9486 ResolveTypeFromClass(current_class(), finalization, &type); 9487 ResolveTypeFromClass(current_class(), finalization, &type);
9487 if (finalization >= ClassFinalizer::kCanonicalize) { 9488 if (finalization >= ClassFinalizer::kCanonicalize) {
9488 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); 9489 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization);
9489 } 9490 }
9490 } 9491 }
9491 return type.raw(); 9492 return type.raw();
9492 } 9493 }
9493 9494
9494 9495
9495 void Parser::CheckConstructorCallTypeArguments( 9496 void Parser::CheckConstructorCallTypeArguments(
9496 intptr_t pos, Function& constructor, 9497 intptr_t pos, const Function& constructor,
9497 const TypeArguments& type_arguments) { 9498 const TypeArguments& type_arguments) {
9498 if (!type_arguments.IsNull()) { 9499 if (!type_arguments.IsNull()) {
9499 const Class& constructor_class = Class::Handle(constructor.Owner()); 9500 const Class& constructor_class = Class::Handle(constructor.Owner());
9500 ASSERT(!constructor_class.IsNull()); 9501 ASSERT(!constructor_class.IsNull());
9501 ASSERT(constructor_class.is_finalized()); 9502 ASSERT(constructor_class.is_finalized());
9502 ASSERT(type_arguments.IsCanonical()); 9503 ASSERT(type_arguments.IsCanonical());
9503 // Do not report the expected vs. actual number of type arguments, because 9504 // Do not report the expected vs. actual number of type arguments, because
9504 // the type argument vector is flattened and raw types are allowed. 9505 // the type argument vector is flattened and raw types are allowed.
9505 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { 9506 if (type_arguments.Length() != constructor_class.NumTypeArguments()) {
9506 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); 9507 ErrorMsg(pos, "wrong number of type arguments passed to constructor");
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
10285 for (int i = 0; i < values.length(); i++) { 10286 for (int i = 0; i < values.length(); i++) {
10286 ASSERT(values[i]->IsLiteralNode()); 10287 ASSERT(values[i]->IsLiteralNode());
10287 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); 10288 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal());
10288 } 10289 }
10289 10290
10290 // Build argument array to pass to the interpolation function. 10291 // Build argument array to pass to the interpolation function.
10291 const Array& interpolate_arg = Array::Handle(isolate(), Array::New(1)); 10292 const Array& interpolate_arg = Array::Handle(isolate(), Array::New(1));
10292 interpolate_arg.SetAt(0, value_arr); 10293 interpolate_arg.SetAt(0, value_arr);
10293 10294
10294 // Call interpolation function. 10295 // Call interpolation function.
10295 String& concatenated = String::ZoneHandle(isolate()); 10296 Object& result = Object::Handle(isolate());
10296 { 10297 {
10297 PAUSETIMERSCOPE(isolate(), time_compilation); 10298 PAUSETIMERSCOPE(isolate(), time_compilation);
10298 concatenated ^= DartEntry::InvokeFunction(func, interpolate_arg); 10299 result = DartEntry::InvokeFunction(func, interpolate_arg);
10299 } 10300 }
10300 if (concatenated.IsUnhandledException()) { 10301 if (result.IsUnhandledException()) {
10301 ErrorMsg("Exception thrown in Parser::Interpolate"); 10302 ErrorMsg("%s", Error::Cast(result).ToErrorCString());
10302 } 10303 }
10304 String& concatenated = String::ZoneHandle(isolate());
10305 concatenated ^= result.raw();
10303 concatenated = Symbols::New(concatenated); 10306 concatenated = Symbols::New(concatenated);
10304 return concatenated; 10307 return concatenated;
10305 } 10308 }
10306 10309
10307 10310
10308 // A string literal consists of the concatenation of the next n tokens 10311 // A string literal consists of the concatenation of the next n tokens
10309 // that satisfy the EBNF grammar: 10312 // that satisfy the EBNF grammar:
10310 // literal = kSTRING {{ interpol } kSTRING } 10313 // literal = kSTRING {{ interpol } kSTRING }
10311 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) 10314 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END)
10312 // In other words, the scanner breaks down interpolated strings so that 10315 // In other words, the scanner breaks down interpolated strings so that
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
10946 void Parser::SkipQualIdent() { 10949 void Parser::SkipQualIdent() {
10947 ASSERT(IsIdentifier()); 10950 ASSERT(IsIdentifier());
10948 ConsumeToken(); 10951 ConsumeToken();
10949 if (CurrentToken() == Token::kPERIOD) { 10952 if (CurrentToken() == Token::kPERIOD) {
10950 ConsumeToken(); // Consume the kPERIOD token. 10953 ConsumeToken(); // Consume the kPERIOD token.
10951 ExpectIdentifier("identifier expected after '.'"); 10954 ExpectIdentifier("identifier expected after '.'");
10952 } 10955 }
10953 } 10956 }
10954 10957
10955 } // namespace dart 10958 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | runtime/vm/symbols.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698