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

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

Issue 10964058: Support redirecting factory constructors in the VM (issue 3969). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 "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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698