| 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 |