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 "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 Loading... |
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 Loading... |
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 Loading... |
1333 ASSERT(desc.NamedCount() == params.num_optional_parameters); | 1333 ASSERT(desc.NamedCount() == params.num_optional_parameters); |
1334 | 1334 |
1335 SetupDefaultsForOptionalParams(¶ms, default_values); | 1335 SetupDefaultsForOptionalParams(¶ms, 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(¶ms, current_block_->scope); | 1339 AddFormalParamsToScope(¶ms, 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |