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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 bool has_external; | 512 bool has_external; |
513 bool has_final; | 513 bool has_final; |
514 bool has_const; | 514 bool has_const; |
515 bool has_static; | 515 bool has_static; |
516 bool has_var; | 516 bool has_var; |
517 bool has_factory; | 517 bool has_factory; |
518 bool has_operator; | 518 bool has_operator; |
519 const AbstractType* type; | 519 const AbstractType* type; |
520 intptr_t name_pos; | 520 intptr_t name_pos; |
521 String* name; | 521 String* name; |
522 // For constructors: NULL or redirected constructor. | 522 // For constructors: NULL or name of redirected to constructor. |
523 String* redirect_name; | 523 String* redirect_name; |
524 // For constructors: NULL for unnamed constructor, | 524 // For constructors: NULL for unnamed constructor, |
525 // identifier after classname for named constructors. | 525 // identifier after classname for named constructors. |
526 String* constructor_name; | 526 String* constructor_name; |
527 ParamList params; | 527 ParamList params; |
528 RawFunction::Kind kind; | 528 RawFunction::Kind kind; |
529 }; | 529 }; |
530 | 530 |
531 | 531 |
532 class ClassDesc : public ValueObject { | 532 class ClassDesc : public ValueObject { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 const Script& script = Script::Handle(isolate, func.script()); | 701 const Script& script = Script::Handle(isolate, func.script()); |
702 Parser parser(script, func, func.token_pos()); | 702 Parser parser(script, func, func.token_pos()); |
703 SequenceNode* node_sequence = NULL; | 703 SequenceNode* node_sequence = NULL; |
704 Array& default_parameter_values = Array::Handle(isolate, Array::null()); | 704 Array& default_parameter_values = Array::Handle(isolate, Array::null()); |
705 switch (func.kind()) { | 705 switch (func.kind()) { |
706 case RawFunction::kRegularFunction: | 706 case RawFunction::kRegularFunction: |
707 case RawFunction::kClosureFunction: | 707 case RawFunction::kClosureFunction: |
708 case RawFunction::kGetterFunction: | 708 case RawFunction::kGetterFunction: |
709 case RawFunction::kSetterFunction: | 709 case RawFunction::kSetterFunction: |
710 case RawFunction::kConstructor: | 710 case RawFunction::kConstructor: |
| 711 // The call to a redirecting factory is redirected. |
| 712 ASSERT(!func.IsRedirectingFactory()); |
711 node_sequence = parser.ParseFunc(func, default_parameter_values); | 713 node_sequence = parser.ParseFunc(func, default_parameter_values); |
712 break; | 714 break; |
713 case RawFunction::kImplicitGetter: | 715 case RawFunction::kImplicitGetter: |
714 ASSERT(!func.is_static()); | 716 ASSERT(!func.is_static()); |
715 node_sequence = parser.ParseInstanceGetter(func); | 717 node_sequence = parser.ParseInstanceGetter(func); |
716 break; | 718 break; |
717 case RawFunction::kImplicitSetter: | 719 case RawFunction::kImplicitSetter: |
718 ASSERT(!func.is_static()); | 720 ASSERT(!func.is_static()); |
719 node_sequence = parser.ParseInstanceSetter(func); | 721 node_sequence = parser.ParseInstanceSetter(func); |
720 break; | 722 break; |
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2353 "static method '%s' cannot be abstract", | 2355 "static method '%s' cannot be abstract", |
2354 method->name->ToCString()); | 2356 method->name->ToCString()); |
2355 } | 2357 } |
2356 if (method->has_const && !(method->IsConstructor() || method->IsFactory())) { | 2358 if (method->has_const && !(method->IsConstructor() || method->IsFactory())) { |
2357 ErrorMsg(method->name_pos, "'const' not allowed for methods"); | 2359 ErrorMsg(method->name_pos, "'const' not allowed for methods"); |
2358 } | 2360 } |
2359 if (method->IsFactoryOrConstructor() && method->has_abstract) { | 2361 if (method->IsFactoryOrConstructor() && method->has_abstract) { |
2360 ErrorMsg(method->name_pos, "constructor cannot be abstract"); | 2362 ErrorMsg(method->name_pos, "constructor cannot be abstract"); |
2361 } | 2363 } |
2362 if (method->IsConstructor() && method->has_const) { | 2364 if (method->IsConstructor() && method->has_const) { |
2363 Class& cls = Class::ZoneHandle(library_.LookupClass(members->class_name())); | 2365 Class& cls = Class::Handle(library_.LookupClass(members->class_name())); |
2364 cls.set_is_const(); | 2366 cls.set_is_const(); |
2365 } | 2367 } |
2366 if (method->has_abstract && members->is_interface()) { | 2368 if (method->has_abstract && members->is_interface()) { |
2367 ErrorMsg(method->name_pos, | 2369 ErrorMsg(method->name_pos, |
2368 "'abstract' method only allowed in class definition"); | 2370 "'abstract' method only allowed in class definition"); |
2369 } | 2371 } |
2370 if (method->has_external && members->is_interface()) { | 2372 if (method->has_external && members->is_interface()) { |
2371 ErrorMsg(method->name_pos, | 2373 ErrorMsg(method->name_pos, |
2372 "'external' method only allowed in class definition"); | 2374 "'external' method only allowed in class definition"); |
2373 } | 2375 } |
2374 | 2376 |
2375 // Parse the formal parameters. | 2377 // Parse the formal parameters. |
2376 const bool are_implicitly_final = method->has_const; | 2378 const bool are_implicitly_final = method->has_const; |
2377 const bool allow_explicit_default_values = true; | 2379 const bool allow_explicit_default_values = true; |
2378 const intptr_t formal_param_pos = TokenPos(); | 2380 const intptr_t formal_param_pos = TokenPos(); |
2379 method->params.Clear(); | 2381 method->params.Clear(); |
2380 // Static functions do not have a receiver. | 2382 // Static functions do not have a receiver. |
2381 // The first parameter of a factory is the AbstractTypeArguments vector of | 2383 // The first parameter of a factory is the AbstractTypeArguments vector of |
2382 // the type of the instance to be allocated. | 2384 // the type of the instance to be allocated. |
2383 if (!method->has_static || method->IsConstructor()) { | 2385 if (!method->has_static || method->IsConstructor()) { |
2384 method->params.AddReceiver(ReceiverType(formal_param_pos)); | 2386 method->params.AddReceiver(ReceiverType(formal_param_pos)); |
2385 } else if (method->has_factory) { | 2387 } else if (method->IsFactory()) { |
2386 method->params.AddFinalParameter( | 2388 method->params.AddFinalParameter( |
2387 formal_param_pos, | 2389 formal_param_pos, |
2388 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), | 2390 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), |
2389 &Type::ZoneHandle(Type::DynamicType())); | 2391 &Type::ZoneHandle(Type::DynamicType())); |
2390 } | 2392 } |
2391 // Constructors have an implicit parameter for the construction phase. | 2393 // Constructors have an implicit parameter for the construction phase. |
2392 if (method->IsConstructor()) { | 2394 if (method->IsConstructor()) { |
2393 method->params.AddFinalParameter( | 2395 method->params.AddFinalParameter( |
2394 TokenPos(), | 2396 TokenPos(), |
2395 &String::ZoneHandle(Symbols::PhaseParameter()), | 2397 &String::ZoneHandle(Symbols::PhaseParameter()), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2436 expected_num_parameters = (method->has_static) ? 1 : 2; | 2438 expected_num_parameters = (method->has_static) ? 1 : 2; |
2437 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); | 2439 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); |
2438 } | 2440 } |
2439 if ((method->params.num_fixed_parameters != expected_num_parameters) || | 2441 if ((method->params.num_fixed_parameters != expected_num_parameters) || |
2440 (method->params.num_optional_parameters != 0)) { | 2442 (method->params.num_optional_parameters != 0)) { |
2441 ErrorMsg(method->name_pos, "illegal %s parameters", | 2443 ErrorMsg(method->name_pos, "illegal %s parameters", |
2442 method->IsGetter() ? "getter" : "setter"); | 2444 method->IsGetter() ? "getter" : "setter"); |
2443 } | 2445 } |
2444 } | 2446 } |
2445 | 2447 |
2446 // Parse initializers. | 2448 // Parse redirecting factory constructor. |
2447 if (CurrentToken() == Token::kCOLON) { | 2449 Type& redirection_type = Type::Handle(); |
| 2450 String& redirection_identifier = String::Handle(); |
| 2451 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
| 2452 ConsumeToken(); |
| 2453 const intptr_t type_pos = TokenPos(); |
| 2454 const AbstractType& type = AbstractType::Handle( |
| 2455 ParseType(ClassFinalizer::kTryResolve)); |
| 2456 if (type.IsTypeParameter()) { |
| 2457 // TODO(regis): Spec is not clear. Throw dynamic error or report |
| 2458 // compile-time error? Same question for new and const operators. |
| 2459 ErrorMsg(type_pos, "factory may not redirect via a type parameter"); |
| 2460 } |
| 2461 redirection_type ^= type.raw(); |
| 2462 if (CurrentToken() == Token::kPERIOD) { |
| 2463 // Named constructor or factory. |
| 2464 ConsumeToken(); |
| 2465 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 2466 } |
| 2467 } else if (CurrentToken() == Token::kCOLON) { |
| 2468 // Parse initializers. |
2448 if (!method->IsConstructor()) { | 2469 if (!method->IsConstructor()) { |
2449 ErrorMsg("initializers only allowed on constructors"); | 2470 ErrorMsg("initializers only allowed on constructors"); |
2450 } | 2471 } |
2451 if ((LookaheadToken(1) == Token::kTHIS) && | 2472 if ((LookaheadToken(1) == Token::kTHIS) && |
2452 ((LookaheadToken(2) == Token::kLPAREN) || | 2473 ((LookaheadToken(2) == Token::kLPAREN) || |
2453 LookaheadToken(4) == Token::kLPAREN)) { | 2474 LookaheadToken(4) == Token::kLPAREN)) { |
2454 // Redirected constructor: either this(...) or this.xxx(...). | 2475 // Redirected constructor: either this(...) or this.xxx(...). |
2455 if (method->params.has_field_initializer) { | 2476 if (method->params.has_field_initializer) { |
2456 // Constructors that redirect to another constructor must not | 2477 // Constructors that redirect to another constructor must not |
2457 // initialize any fields using field initializer parameters. | 2478 // initialize any fields using field initializer parameters. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2531 } | 2552 } |
2532 if (method->redirect_name != NULL) { | 2553 if (method->redirect_name != NULL) { |
2533 ErrorMsg(method->name_pos, | 2554 ErrorMsg(method->name_pos, |
2534 "Constructor with redirection may not have a function body"); | 2555 "Constructor with redirection may not have a function body"); |
2535 } | 2556 } |
2536 ParseNativeDeclaration(); | 2557 ParseNativeDeclaration(); |
2537 } else { | 2558 } else { |
2538 // We haven't found a method body. Issue error if one is required. | 2559 // We haven't found a method body. Issue error if one is required. |
2539 const bool must_have_body = | 2560 const bool must_have_body = |
2540 !members->is_interface() && | 2561 !members->is_interface() && |
2541 method->has_static && !method->has_external; | 2562 method->has_static && |
| 2563 !method->has_external && |
| 2564 redirection_type.IsNull(); |
2542 if (must_have_body) { | 2565 if (must_have_body) { |
2543 ErrorMsg(method->name_pos, | 2566 ErrorMsg(method->name_pos, |
2544 "function body expected for method '%s'", | 2567 "function body expected for method '%s'", |
2545 method->name->ToCString()); | 2568 method->name->ToCString()); |
2546 } | 2569 } |
2547 | 2570 |
2548 if (CurrentToken() == Token::kSEMICOLON) { | 2571 if (CurrentToken() == Token::kSEMICOLON) { |
2549 ConsumeToken(); | 2572 ConsumeToken(); |
2550 if (!members->is_interface() && | 2573 if (!members->is_interface() && |
2551 !method->has_static && | 2574 !method->has_static && |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2588 function_kind, | 2611 function_kind, |
2589 method->has_static, | 2612 method->has_static, |
2590 method->has_const, | 2613 method->has_const, |
2591 method->has_abstract, | 2614 method->has_abstract, |
2592 method->has_external, | 2615 method->has_external, |
2593 current_class(), | 2616 current_class(), |
2594 method_pos)); | 2617 method_pos)); |
2595 func.set_result_type(*method->type); | 2618 func.set_result_type(*method->type); |
2596 func.set_end_token_pos(method_end_pos); | 2619 func.set_end_token_pos(method_end_pos); |
2597 | 2620 |
| 2621 // If this method is a redirecting factory, set the redirection information. |
| 2622 if (!redirection_type.IsNull()) { |
| 2623 ASSERT(func.IsFactory()); |
| 2624 func.SetRedirectionType(redirection_type); |
| 2625 if (!redirection_identifier.IsNull()) { |
| 2626 func.SetRedirectionIdentifier(redirection_identifier); |
| 2627 } |
| 2628 } |
| 2629 |
2598 // No need to resolve parameter types yet, or add parameters to local scope. | 2630 // No need to resolve parameter types yet, or add parameters to local scope. |
2599 ASSERT(is_top_level_); | 2631 ASSERT(is_top_level_); |
2600 AddFormalParamsToFunction(&method->params, func); | 2632 AddFormalParamsToFunction(&method->params, func); |
2601 members->AddFunction(func); | 2633 members->AddFunction(func); |
2602 } | 2634 } |
2603 | 2635 |
2604 | 2636 |
2605 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 2637 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
2606 TRACE_PARSER("ParseFieldDefinition"); | 2638 TRACE_PARSER("ParseFieldDefinition"); |
2607 // The parser has read the first field name and is now at the token | 2639 // The parser has read the first field name and is now at the token |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2964 if (member.has_factory) { | 2996 if (member.has_factory) { |
2965 ErrorMsg("factory constructors are not allowed in interfaces"); | 2997 ErrorMsg("factory constructors are not allowed in interfaces"); |
2966 } else { | 2998 } else { |
2967 ErrorMsg("static methods are not allowed in interfaces"); | 2999 ErrorMsg("static methods are not allowed in interfaces"); |
2968 } | 3000 } |
2969 } | 3001 } |
2970 // Constructor or method. | 3002 // Constructor or method. |
2971 if (member.type == NULL) { | 3003 if (member.type == NULL) { |
2972 member.type = &Type::ZoneHandle(Type::DynamicType()); | 3004 member.type = &Type::ZoneHandle(Type::DynamicType()); |
2973 } | 3005 } |
| 3006 ASSERT(member.IsFactory() == member.has_factory); |
2974 ParseMethodOrConstructor(members, &member); | 3007 ParseMethodOrConstructor(members, &member); |
2975 if (member.has_operator) { | 3008 if (member.has_operator) { |
2976 CheckOperatorArity(member, operator_token); | 3009 CheckOperatorArity(member, operator_token); |
2977 } | 3010 } |
2978 } else if (CurrentToken() == Token::kSEMICOLON || | 3011 } else if (CurrentToken() == Token::kSEMICOLON || |
2979 CurrentToken() == Token::kCOMMA || | 3012 CurrentToken() == Token::kCOMMA || |
2980 CurrentToken() == Token::kASSIGN) { | 3013 CurrentToken() == Token::kASSIGN) { |
2981 // Field definition. | 3014 // Field definition. |
2982 if (member.has_const) { | 3015 if (member.has_const) { |
2983 // const fields are implicitly final. | 3016 // const fields are implicitly final. |
(...skipping 5728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8712 AstNode* Parser::ParseNewOperator() { | 8745 AstNode* Parser::ParseNewOperator() { |
8713 TRACE_PARSER("ParseNewOperator"); | 8746 TRACE_PARSER("ParseNewOperator"); |
8714 const intptr_t new_pos = TokenPos(); | 8747 const intptr_t new_pos = TokenPos(); |
8715 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 8748 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
8716 bool is_const = (CurrentToken() == Token::kCONST); | 8749 bool is_const = (CurrentToken() == Token::kCONST); |
8717 ConsumeToken(); | 8750 ConsumeToken(); |
8718 if (!IsIdentifier()) { | 8751 if (!IsIdentifier()) { |
8719 ErrorMsg("type name expected"); | 8752 ErrorMsg("type name expected"); |
8720 } | 8753 } |
8721 intptr_t type_pos = TokenPos(); | 8754 intptr_t type_pos = TokenPos(); |
8722 const AbstractType& type = AbstractType::Handle( | 8755 AbstractType& type = AbstractType::Handle( |
8723 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); | 8756 ParseType(ClassFinalizer::kCanonicalizeWellFormed)); |
8724 // Malformed bounds never result in a compile time error, therefore, the | 8757 // Malformed bounds never result in a compile time error, therefore, the |
8725 // parsed type may be malformed although we requested kCanonicalizeWellFormed. | 8758 // parsed type may be malformed although we requested kCanonicalizeWellFormed. |
8726 // In that case, we throw a dynamic type error instead of calling the | 8759 // In that case, we throw a dynamic type error instead of calling the |
8727 // constructor. | 8760 // constructor. |
8728 if (type.IsTypeParameter()) { | 8761 if (type.IsTypeParameter()) { |
8729 ErrorMsg(type_pos, | 8762 ErrorMsg(type_pos, |
8730 "type parameter '%s' cannot be instantiated", | 8763 "type parameter '%s' cannot be instantiated", |
8731 String::Handle(type.UserVisibleName()).ToCString()); | 8764 String::Handle(type.UserVisibleName()).ToCString()); |
8732 } | 8765 } |
8733 if (type.IsDynamicType()) { | 8766 if (type.IsDynamicType()) { |
8734 ErrorMsg(type_pos, "Dynamic cannot be instantiated"); | 8767 ErrorMsg(type_pos, "Dynamic cannot be instantiated"); |
8735 } | 8768 } |
8736 const Class& type_class = Class::Handle(type.type_class()); | 8769 Class& type_class = Class::Handle(type.type_class()); |
8737 const String& type_class_name = String::Handle(type_class.Name()); | 8770 const String& type_class_name = String::Handle(type_class.Name()); |
8738 AbstractTypeArguments& type_arguments = | 8771 AbstractTypeArguments& type_arguments = |
8739 AbstractTypeArguments::ZoneHandle(type.arguments()); | 8772 AbstractTypeArguments::ZoneHandle(type.arguments()); |
8740 | 8773 |
8741 // The constructor class and its name are those of the parsed type, unless the | 8774 // The constructor class and its name are those of the parsed type, unless the |
8742 // parsed type is an interface and a default factory class is specified, in | 8775 // parsed type is an interface and a default factory class is specified, in |
8743 // which case constructor_class and constructor_class_name are modified below. | 8776 // which case constructor_class and constructor_class_name are modified below. |
8744 Class& constructor_class = Class::ZoneHandle(type_class.raw()); | 8777 Class& constructor_class = Class::ZoneHandle(type_class.raw()); |
8745 String& constructor_class_name = String::Handle(type_class_name.raw()); | 8778 String& constructor_class_name = String::Handle(type_class_name.raw()); |
8746 | 8779 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8821 ASSERT(!constructor_class.is_interface()); | 8854 ASSERT(!constructor_class.is_interface()); |
8822 } | 8855 } |
8823 | 8856 |
8824 // Make sure that an appropriate constructor exists. | 8857 // Make sure that an appropriate constructor exists. |
8825 const String& constructor_name = | 8858 const String& constructor_name = |
8826 BuildConstructorName(constructor_class_name, named_constructor); | 8859 BuildConstructorName(constructor_class_name, named_constructor); |
8827 Function& constructor = Function::ZoneHandle( | 8860 Function& constructor = Function::ZoneHandle( |
8828 constructor_class.LookupConstructor(constructor_name)); | 8861 constructor_class.LookupConstructor(constructor_name)); |
8829 if (constructor.IsNull()) { | 8862 if (constructor.IsNull()) { |
8830 constructor = constructor_class.LookupFactory(constructor_name); | 8863 constructor = constructor_class.LookupFactory(constructor_name); |
8831 // A factory does not have the implicit 'phase' parameter. | 8864 if (constructor.IsNull()) { |
8832 arguments_length -= 1; | 8865 const String& external_constructor_name = |
8833 } | 8866 (named_constructor ? constructor_name : constructor_class_name); |
8834 if (constructor.IsNull()) { | 8867 ErrorMsg(type_pos, |
8835 const String& external_constructor_name = | 8868 "class '%s' has no constructor or factory named '%s'", |
8836 (named_constructor ? constructor_name : constructor_class_name); | 8869 String::Handle(constructor_class.Name()).ToCString(), |
8837 ErrorMsg(type_pos, | 8870 external_constructor_name.ToCString()); |
8838 "class '%s' has no constructor or factory named '%s'", | 8871 } else if (constructor.IsRedirectingFactory()) { |
8839 String::Handle(constructor_class.Name()).ToCString(), | 8872 type = constructor.RedirectionType(); |
8840 external_constructor_name.ToCString()); | 8873 constructor = constructor.RedirectionTarget(); |
| 8874 if (constructor.IsNull()) { |
| 8875 // TODO(regis): We normally report a compile-time error if the |
| 8876 // constructor is not found. See above. However, we should throw a |
| 8877 // dynamic error instead. We do it here. This is the first step. |
| 8878 ASSERT(type.IsMalformed()); |
| 8879 } else { |
| 8880 type_class = type.type_class(); |
| 8881 type_arguments = type.arguments(); |
| 8882 constructor_class = constructor.Owner(); |
| 8883 ASSERT(type_class.raw() == constructor_class.raw()); |
| 8884 } |
| 8885 } |
| 8886 if (!constructor.IsNull() && constructor.IsFactory()) { |
| 8887 // A factory does not have the implicit 'phase' parameter. |
| 8888 arguments_length -= 1; |
| 8889 } |
8841 } | 8890 } |
8842 | 8891 |
8843 // It is ok to call a factory method of an abstract class, but it is | 8892 // It is ok to call a factory method of an abstract class, but it is |
8844 // a dynamic error to instantiate an abstract class. | 8893 // a dynamic error to instantiate an abstract class. |
8845 if (constructor_class.is_abstract() && !constructor.IsFactory()) { | 8894 if (!constructor.IsNull() && |
| 8895 constructor_class.is_abstract() && |
| 8896 !constructor.IsFactory()) { |
8846 ArgumentListNode* arguments = new ArgumentListNode(type_pos); | 8897 ArgumentListNode* arguments = new ArgumentListNode(type_pos); |
8847 arguments->Add(new LiteralNode( | 8898 arguments->Add(new LiteralNode( |
8848 TokenPos(), Integer::ZoneHandle(Integer::New(type_pos)))); | 8899 TokenPos(), Integer::ZoneHandle(Integer::New(type_pos)))); |
8849 arguments->Add(new LiteralNode( | 8900 arguments->Add(new LiteralNode( |
8850 TokenPos(), String::ZoneHandle(constructor_class_name.raw()))); | 8901 TokenPos(), String::ZoneHandle(constructor_class_name.raw()))); |
8851 const String& cls_name = | 8902 const String& cls_name = |
8852 String::Handle(Symbols::AbstractClassInstantiationError()); | 8903 String::Handle(Symbols::AbstractClassInstantiationError()); |
8853 const String& func_name = String::Handle(Symbols::ThrowNew()); | 8904 const String& func_name = String::Handle(Symbols::ThrowNew()); |
8854 return MakeStaticCall(cls_name, func_name, arguments); | 8905 return MakeStaticCall(cls_name, func_name, arguments); |
8855 } | 8906 } |
8856 | 8907 |
8857 String& error_message = String::Handle(); | 8908 String& error_message = String::Handle(); |
8858 if (!constructor.AreValidArguments(arguments_length, | 8909 if (!constructor.IsNull() && |
| 8910 !constructor.AreValidArguments(arguments_length, |
8859 arguments->names(), | 8911 arguments->names(), |
8860 &error_message)) { | 8912 &error_message)) { |
8861 const String& external_constructor_name = | 8913 const String& external_constructor_name = |
8862 (named_constructor ? constructor_name : constructor_class_name); | 8914 (named_constructor ? constructor_name : constructor_class_name); |
8863 ErrorMsg(call_pos, | 8915 ErrorMsg(call_pos, |
8864 "invalid arguments passed to constructor '%s' for class '%s': %s", | 8916 "invalid arguments passed to constructor '%s' for class '%s': %s", |
8865 external_constructor_name.ToCString(), | 8917 external_constructor_name.ToCString(), |
8866 String::Handle(constructor_class.Name()).ToCString(), | 8918 String::Handle(constructor_class.Name()).ToCString(), |
8867 error_message.ToCString()); | 8919 error_message.ToCString()); |
8868 } | 8920 } |
8869 | 8921 |
8870 // Now that the constructor to be called is identified, finalize the type | 8922 // Now that the constructor to be called is identified, finalize the type |
8871 // argument vector to be passed. | 8923 // argument vector to be passed. |
8872 // The type argument vector of the parsed type was finalized in ParseType. | 8924 // The type argument vector of the parsed type was finalized in ParseType. |
8873 // If the constructor class was changed from the interface class to the | 8925 // If the constructor class was changed from the interface class to the |
8874 // factory class, we need to finalize the type argument vector again, because | 8926 // factory class, we need to finalize the type argument vector again, because |
8875 // it may be longer due to the factory class extending a class, or/and because | 8927 // it may be longer due to the factory class extending a class, or/and because |
8876 // the bounds on the factory class may be tighter than on the interface. | 8928 // the bounds on the factory class may be tighter than on the interface. |
8877 if (constructor_class.raw() != type_class.raw()) { | 8929 if (!constructor.IsNull() && (constructor_class.raw() != type_class.raw())) { |
8878 const intptr_t num_type_parameters = constructor_class.NumTypeParameters(); | 8930 const intptr_t num_type_parameters = constructor_class.NumTypeParameters(); |
8879 TypeArguments& temp_type_arguments = TypeArguments::Handle(); | 8931 TypeArguments& temp_type_arguments = TypeArguments::Handle(); |
8880 if (!type_arguments.IsNull()) { | 8932 if (!type_arguments.IsNull()) { |
8881 // Copy the parsed type arguments starting at offset 0, because interfaces | 8933 // Copy the parsed type arguments starting at offset 0, because interfaces |
8882 // have no super types. | 8934 // have no super types. |
8883 ASSERT(type_class.NumTypeArguments() == type_class.NumTypeParameters()); | 8935 ASSERT(type_class.NumTypeArguments() == type_class.NumTypeParameters()); |
8884 const intptr_t num_type_arguments = type_arguments.Length(); | 8936 const intptr_t num_type_arguments = type_arguments.Length(); |
8885 temp_type_arguments = TypeArguments::New(num_type_parameters, Heap::kNew); | 8937 temp_type_arguments = TypeArguments::New(num_type_parameters, Heap::kNew); |
8886 AbstractType& type_argument = AbstractType::Handle(); | 8938 AbstractType& type_argument = AbstractType::Handle(); |
8887 for (intptr_t i = 0; i < num_type_parameters; i++) { | 8939 for (intptr_t i = 0; i < num_type_parameters; i++) { |
(...skipping 14 matching lines...) Expand all Loading... |
8902 // of the super type when finalizing the temporary type. | 8954 // of the super type when finalizing the temporary type. |
8903 type_arguments = temp_type.arguments(); | 8955 type_arguments = temp_type.arguments(); |
8904 // The type parameter bounds of the factory class may be more specific than | 8956 // The type parameter bounds of the factory class may be more specific than |
8905 // the type parameter bounds of the interface class. Therefore, although | 8957 // the type parameter bounds of the interface class. Therefore, although |
8906 // type was not malformed, temp_type may be malformed. | 8958 // type was not malformed, temp_type may be malformed. |
8907 if (!type.IsMalformed() && temp_type.IsMalformed()) { | 8959 if (!type.IsMalformed() && temp_type.IsMalformed()) { |
8908 const Error& error = Error::Handle(temp_type.malformed_error()); | 8960 const Error& error = Error::Handle(temp_type.malformed_error()); |
8909 type.set_malformed_error(error); | 8961 type.set_malformed_error(error); |
8910 } | 8962 } |
8911 } | 8963 } |
8912 | 8964 if (type.IsMalformed()) { |
| 8965 // Compile the throw of a dynamic type error due to a bound error or to |
| 8966 // a redirection error. |
| 8967 return ThrowTypeError(type_pos, type); |
| 8968 } |
8913 type_arguments ^= type_arguments.Canonicalize(); | 8969 type_arguments ^= type_arguments.Canonicalize(); |
8914 // Make the constructor call. | 8970 // Make the constructor call. |
8915 AstNode* new_object = NULL; | 8971 AstNode* new_object = NULL; |
8916 if (is_const) { | 8972 if (is_const) { |
8917 if (!constructor.is_const()) { | 8973 if (!constructor.is_const()) { |
8918 ErrorMsg("'const' requires const constructor: '%s'", | 8974 ErrorMsg("'const' requires const constructor: '%s'", |
8919 String::Handle(constructor.name()).ToCString()); | 8975 String::Handle(constructor.name()).ToCString()); |
8920 } | 8976 } |
8921 if (type.IsMalformed()) { | |
8922 // Compile the throw of a dynamic type error due to a bound error. | |
8923 return ThrowTypeError(type_pos, type); | |
8924 } | |
8925 const Object& constructor_result = Object::Handle( | 8977 const Object& constructor_result = Object::Handle( |
8926 EvaluateConstConstructorCall(constructor_class, | 8978 EvaluateConstConstructorCall(constructor_class, |
8927 type_arguments, | 8979 type_arguments, |
8928 constructor, | 8980 constructor, |
8929 arguments)); | 8981 arguments)); |
8930 if (constructor_result.IsUnhandledException()) { | 8982 if (constructor_result.IsUnhandledException()) { |
8931 new_object = GenerateRethrow(new_pos, constructor_result); | 8983 new_object = GenerateRethrow(new_pos, constructor_result); |
8932 } else { | 8984 } else { |
8933 const Instance& const_instance = Instance::Cast(constructor_result); | 8985 const Instance& const_instance = Instance::Cast(constructor_result); |
8934 new_object = new LiteralNode(new_pos, | 8986 new_object = new LiteralNode(new_pos, |
8935 Instance::ZoneHandle(const_instance.raw())); | 8987 Instance::ZoneHandle(const_instance.raw())); |
8936 } | 8988 } |
8937 } else { | 8989 } else { |
8938 CheckFunctionIsCallable(new_pos, constructor); | 8990 CheckFunctionIsCallable(new_pos, constructor); |
8939 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 8991 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
8940 if (!type_arguments.IsNull() && | 8992 if (!type_arguments.IsNull() && |
8941 !type_arguments.IsInstantiated() && | 8993 !type_arguments.IsInstantiated() && |
8942 (current_block_->scope->function_level() > 0)) { | 8994 (current_block_->scope->function_level() > 0)) { |
8943 // Make sure that the instantiator is captured. | 8995 // Make sure that the instantiator is captured. |
8944 CaptureInstantiator(); | 8996 CaptureInstantiator(); |
8945 } | 8997 } |
8946 if (type.IsMalformed()) { | |
8947 // Compile the throw of a dynamic type error due to a bound error. | |
8948 return ThrowTypeError(type_pos, type); | |
8949 } | |
8950 // If the type argument vector is not instantiated, we verify in checked | 8998 // If the type argument vector is not instantiated, we verify in checked |
8951 // mode at runtime that it is within its declared bounds. | 8999 // mode at runtime that it is within its declared bounds. |
8952 new_object = CreateConstructorCallNode( | 9000 new_object = CreateConstructorCallNode( |
8953 new_pos, type_arguments, constructor, arguments); | 9001 new_pos, type_arguments, constructor, arguments); |
8954 } | 9002 } |
8955 return new_object; | 9003 return new_object; |
8956 } | 9004 } |
8957 | 9005 |
8958 | 9006 |
8959 String& Parser::Interpolate(ArrayNode* values) { | 9007 String& Parser::Interpolate(ArrayNode* values) { |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9539 void Parser::SkipQualIdent() { | 9587 void Parser::SkipQualIdent() { |
9540 ASSERT(IsIdentifier()); | 9588 ASSERT(IsIdentifier()); |
9541 ConsumeToken(); | 9589 ConsumeToken(); |
9542 if (CurrentToken() == Token::kPERIOD) { | 9590 if (CurrentToken() == Token::kPERIOD) { |
9543 ConsumeToken(); // Consume the kPERIOD token. | 9591 ConsumeToken(); // Consume the kPERIOD token. |
9544 ExpectIdentifier("identifier expected after '.'"); | 9592 ExpectIdentifier("identifier expected after '.'"); |
9545 } | 9593 } |
9546 } | 9594 } |
9547 | 9595 |
9548 } // namespace dart | 9596 } // namespace dart |
OLD | NEW |