| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 const String& interface_name = String::Handle(interface.Name()); | 365 const String& interface_name = String::Handle(interface.Name()); |
| 366 const String& factory_name = String::Handle(factory_class.Name()); | 366 const String& factory_name = String::Handle(factory_class.Name()); |
| 367 const Script& script = Script::Handle(interface.script()); | 367 const Script& script = Script::Handle(interface.script()); |
| 368 ReportError(script, unresolved_factory_class.token_index(), | 368 ReportError(script, unresolved_factory_class.token_index(), |
| 369 "default clause of interface '%s' names non-class '%s'.\n", | 369 "default clause of interface '%s' names non-class '%s'.\n", |
| 370 interface_name.ToCString(), | 370 interface_name.ToCString(), |
| 371 factory_name.ToCString()); | 371 factory_name.ToCString()); |
| 372 } | 372 } |
| 373 interface.set_factory_class(factory_class); | 373 interface.set_factory_class(factory_class); |
| 374 ResolveAndFinalizeUpperBounds(factory_class); | 374 ResolveAndFinalizeUpperBounds(factory_class); |
| 375 const intptr_t num_factory_type_params = factory_class.NumTypeParameters(); | |
| 376 const Class& factory_signature_class = Class::Handle( | 375 const Class& factory_signature_class = Class::Handle( |
| 377 unresolved_factory_class.factory_signature_class()); | 376 unresolved_factory_class.factory_signature_class()); |
| 378 ASSERT(!factory_signature_class.IsNull()); | 377 ASSERT(!factory_signature_class.IsNull()); |
| 379 const intptr_t num_default_type_params = | |
| 380 factory_signature_class.NumTypeParameters(); | |
| 381 // If a type parameter list is included in the default factory clause (it | 378 // If a type parameter list is included in the default factory clause (it |
| 382 // can be omitted), verify that it matches the list of type parameters of | 379 // can be omitted), verify that it matches the list of type parameters of |
| 383 // the factory class in number, names, and bounds. | 380 // the factory class in number, names, and bounds. |
| 384 if (num_default_type_params > 0) { | 381 if (factory_signature_class.NumTypeParameters() > 0) { |
| 385 ResolveAndFinalizeUpperBounds(factory_signature_class); | 382 ResolveAndFinalizeUpperBounds(factory_signature_class); |
| 386 String& expected_type_name = String::Handle(); | 383 const TypeArguments& expected_type_parameters = |
| 387 String& actual_type_name = String::Handle(); | 384 TypeArguments::Handle(factory_signature_class.type_parameters()); |
| 388 AbstractType& expected_type_extends = AbstractType::Handle(); | 385 const TypeArguments& actual_type_parameters = |
| 389 AbstractType& actual_type_extends = AbstractType::Handle(); | 386 TypeArguments::Handle(factory_class.type_parameters()); |
| 390 const Array& expected_type_names = | 387 const TypeArguments& expected_type_parameter_bounds = |
| 391 Array::Handle(factory_signature_class.type_parameters()); | 388 TypeArguments::Handle(factory_signature_class.type_parameter_bounds()); |
| 392 const Array& actual_type_names = | 389 const TypeArguments& actual_type_parameter_bounds = |
| 393 Array::Handle(factory_class.type_parameters()); | 390 TypeArguments::Handle(factory_class.type_parameter_bounds()); |
| 394 const TypeArguments& expected_extends_array = | 391 if (!AbstractTypeArguments::AreEqual(expected_type_parameters, |
| 395 TypeArguments::Handle(factory_signature_class.type_parameter_extends()); | 392 actual_type_parameters) || |
| 396 const TypeArguments& actual_extends_array = | 393 !AbstractTypeArguments::AreEqual(expected_type_parameter_bounds, |
| 397 TypeArguments::Handle(factory_class.type_parameter_extends()); | 394 actual_type_parameter_bounds)) { |
| 398 bool mismatch = num_factory_type_params != num_default_type_params; | |
| 399 for (intptr_t i = 0; !mismatch && (i < num_default_type_params); i++) { | |
| 400 expected_type_name ^= expected_type_names.At(i); | |
| 401 actual_type_name ^= actual_type_names.At(i); | |
| 402 expected_type_extends = expected_extends_array.TypeAt(i); | |
| 403 actual_type_extends = actual_extends_array.TypeAt(i); | |
| 404 if (!expected_type_name.Equals(actual_type_name) || | |
| 405 !expected_type_extends.Equals(actual_type_extends)) { | |
| 406 mismatch = true; | |
| 407 } | |
| 408 } | |
| 409 if (mismatch) { | |
| 410 const String& interface_name = String::Handle(interface.Name()); | 395 const String& interface_name = String::Handle(interface.Name()); |
| 411 const String& factory_name = String::Handle(factory_class.Name()); | 396 const String& factory_name = String::Handle(factory_class.Name()); |
| 412 const Script& script = Script::Handle(interface.script()); | 397 const Script& script = Script::Handle(interface.script()); |
| 413 ReportError(script, unresolved_factory_class.token_index(), | 398 ReportError(script, unresolved_factory_class.token_index(), |
| 414 "mismatch in number, names, or bounds of type parameters " | 399 "mismatch in number, names, or bounds of type parameters " |
| 415 "between default clause of interface '%s' and actual factory " | 400 "between default clause of interface '%s' and actual factory " |
| 416 "class '%s'.\n", | 401 "class '%s'.\n", |
| 417 interface_name.ToCString(), | 402 interface_name.ToCString(), |
| 418 factory_name.ToCString()); | 403 factory_name.ToCString()); |
| 419 } | 404 } |
| 420 } | 405 } |
| 421 // Verify that the type parameters of the factory class and of the interface | 406 // Verify that the type parameters of the factory class and of the interface |
| 422 // have identical names. | 407 // have identical names. |
| 423 String& interface_type_param_name = String::Handle(); | 408 const TypeArguments& interface_type_parameters = |
| 424 String& factory_type_param_name = String::Handle(); | 409 TypeArguments::Handle(interface.type_parameters()); |
| 425 const Array& interface_type_param_names = | 410 const TypeArguments& factory_type_parameters = |
| 426 Array::Handle(interface.type_parameters()); | 411 TypeArguments::Handle(factory_class.type_parameters()); |
| 427 const Array& factory_type_param_names = | 412 if (!AbstractTypeArguments::AreEqual(interface_type_parameters, |
| 428 Array::Handle(factory_class.type_parameters()); | 413 factory_type_parameters)) { |
| 429 const intptr_t num_interface_type_params = interface.NumTypeParameters(); | |
| 430 bool mismatch = num_interface_type_params != num_factory_type_params; | |
| 431 for (intptr_t i = 0; !mismatch && (i < num_factory_type_params); i++) { | |
| 432 interface_type_param_name ^= interface_type_param_names.At(i); | |
| 433 factory_type_param_name ^= factory_type_param_names.At(i); | |
| 434 if (!interface_type_param_name.Equals(factory_type_param_name)) { | |
| 435 mismatch = true; | |
| 436 } | |
| 437 } | |
| 438 if (mismatch) { | |
| 439 const String& interface_name = String::Handle(interface.Name()); | 414 const String& interface_name = String::Handle(interface.Name()); |
| 440 const String& factory_name = String::Handle(factory_class.Name()); | 415 const String& factory_name = String::Handle(factory_class.Name()); |
| 441 const Script& script = Script::Handle(interface.script()); | 416 const Script& script = Script::Handle(interface.script()); |
| 442 ReportError(script, unresolved_factory_class.token_index(), | 417 ReportError(script, unresolved_factory_class.token_index(), |
| 443 "mismatch in number or names of type parameters between " | 418 "mismatch in number or names of type parameters between " |
| 444 "interface '%s' and default factory class '%s'.\n", | 419 "interface '%s' and default factory class '%s'.\n", |
| 445 interface_name.ToCString(), | 420 interface_name.ToCString(), |
| 446 factory_name.ToCString()); | 421 factory_name.ToCString()); |
| 447 } | 422 } |
| 448 } | 423 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 | 509 |
| 535 | 510 |
| 536 // Verify the upper bounds of the type arguments of class cls. | 511 // Verify the upper bounds of the type arguments of class cls. |
| 537 void ClassFinalizer::VerifyUpperBounds(const Class& cls, | 512 void ClassFinalizer::VerifyUpperBounds(const Class& cls, |
| 538 const AbstractTypeArguments& arguments) { | 513 const AbstractTypeArguments& arguments) { |
| 539 ASSERT(FLAG_enable_type_checks); | 514 ASSERT(FLAG_enable_type_checks); |
| 540 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 515 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 541 const intptr_t num_type_params = cls.NumTypeParameters(); | 516 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 542 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | 517 const intptr_t offset = cls.NumTypeArguments() - num_type_params; |
| 543 AbstractType& type = AbstractType::Handle(); | 518 AbstractType& type = AbstractType::Handle(); |
| 544 AbstractType& type_extends = AbstractType::Handle(); | 519 AbstractType& bound = AbstractType::Handle(); |
| 545 const AbstractTypeArguments& extends_array = | 520 const TypeArguments& bounds = |
| 546 AbstractTypeArguments::Handle(cls.type_parameter_extends()); | 521 TypeArguments::Handle(cls.type_parameter_bounds()); |
| 547 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || | 522 ASSERT((bounds.IsNull() && (num_type_params == 0)) || |
| 548 (extends_array.Length() == num_type_params)); | 523 (bounds.Length() == num_type_params)); |
| 549 for (intptr_t i = 0; i < num_type_params; i++) { | 524 for (intptr_t i = 0; i < num_type_params; i++) { |
| 550 type_extends = extends_array.TypeAt(i); | 525 bound = bounds.TypeAt(i); |
| 551 if (!type_extends.IsDynamicType()) { | 526 if (!bound.IsDynamicType()) { |
| 552 type = arguments.TypeAt(offset + i); | 527 type = arguments.TypeAt(offset + i); |
| 553 if (type.IsInstantiated()) { | 528 if (type.IsInstantiated()) { |
| 554 if (!type_extends.IsInstantiated()) { | 529 if (!bound.IsInstantiated()) { |
| 555 type_extends = type_extends.InstantiateFrom(arguments); | 530 bound = bound.InstantiateFrom(arguments); |
| 556 } | 531 } |
| 557 // TODO(regis): Where do we check the constraints when the type is | 532 // TODO(regis): Where do we check the bound when the type is generic? |
| 558 // generic? | 533 if (!type.IsSubtypeOf(bound)) { |
| 559 if (!type.IsSubtypeOf(type_extends)) { | |
| 560 const String& type_argument_name = String::Handle(type.Name()); | 534 const String& type_argument_name = String::Handle(type.Name()); |
| 561 const String& class_name = String::Handle(cls.Name()); | 535 const String& class_name = String::Handle(cls.Name()); |
| 562 const String& extends_name = String::Handle(type_extends.Name()); | 536 const String& bound_name = String::Handle(bound.Name()); |
| 563 const Script& script = Script::Handle(cls.script()); | 537 const Script& script = Script::Handle(cls.script()); |
| 564 ReportError(script, type.token_index(), | 538 ReportError(script, type.token_index(), |
| 565 "type argument '%s' of class '%s' " | 539 "type argument '%s' of class '%s' " |
| 566 "does not extend type '%s'\n", | 540 "does not extend bound '%s'\n", |
| 567 type_argument_name.ToCString(), | 541 type_argument_name.ToCString(), |
| 568 class_name.ToCString(), | 542 class_name.ToCString(), |
| 569 extends_name.ToCString()); | 543 bound_name.ToCString()); |
| 570 } | 544 } |
| 571 } | 545 } |
| 572 } | 546 } |
| 573 } | 547 } |
| 574 const Type& super_type = Type::Handle(cls.super_type()); | 548 const Type& super_type = Type::Handle(cls.super_type()); |
| 575 if (!super_type.IsNull()) { | 549 if (!super_type.IsNull()) { |
| 576 ASSERT(super_type.IsFinalized()); | 550 ASSERT(super_type.IsFinalized()); |
| 577 const Class& super_class = Class::Handle(super_type.type_class()); | 551 const Class& super_class = Class::Handle(super_type.type_class()); |
| 578 VerifyUpperBounds(super_class, arguments); | 552 VerifyUpperBounds(super_class, arguments); |
| 579 } | 553 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 } | 626 } |
| 653 | 627 |
| 654 // The finalized type argument vector needs num_type_arguments types. | 628 // The finalized type argument vector needs num_type_arguments types. |
| 655 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 629 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 656 // The type class has num_type_parameters type parameters. | 630 // The type class has num_type_parameters type parameters. |
| 657 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 631 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 658 | 632 |
| 659 // Initialize the type argument vector. | 633 // Initialize the type argument vector. |
| 660 // Check the number of parsed type arguments, if any. | 634 // Check the number of parsed type arguments, if any. |
| 661 // Specifying no type arguments indicates a raw type, which is not an error. | 635 // Specifying no type arguments indicates a raw type, which is not an error. |
| 662 // However, subtyping constraints are checked below, even for a raw type. | 636 // However, type parameter bounds are checked below, even for a raw type. |
| 663 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 637 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 664 const Script& script = Script::Handle(cls.script()); | 638 const Script& script = Script::Handle(cls.script()); |
| 665 ReportError(script, type.token_index(), | 639 ReportError(script, type.token_index(), |
| 666 "wrong number of type arguments in type '%s'\n", | 640 "wrong number of type arguments in type '%s'\n", |
| 667 String::Handle(type.Name()).ToCString()); | 641 String::Handle(type.Name()).ToCString()); |
| 668 } | 642 } |
| 669 // The full type argument vector consists of the type arguments of the | 643 // The full type argument vector consists of the type arguments of the |
| 670 // super types of type_class, which may be initialized from the parsed | 644 // super types of type_class, which may be initialized from the parsed |
| 671 // type arguments, followed by the parsed type arguments. | 645 // type arguments, followed by the parsed type arguments. |
| 672 if (num_type_arguments > 0) { | 646 if (num_type_arguments > 0) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 } | 740 } |
| 767 super_class = super_class.SuperClass(); | 741 super_class = super_class.SuperClass(); |
| 768 } | 742 } |
| 769 return Class::null(); | 743 return Class::null(); |
| 770 } | 744 } |
| 771 | 745 |
| 772 | 746 |
| 773 // Resolve and finalize the upper bounds of the type parameters of class cls. | 747 // Resolve and finalize the upper bounds of the type parameters of class cls. |
| 774 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { | 748 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { |
| 775 const intptr_t num_type_params = cls.NumTypeParameters(); | 749 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 776 AbstractType& type_extends = AbstractType::Handle(); | 750 AbstractType& bound = AbstractType::Handle(); |
| 777 const AbstractTypeArguments& extends_array = | 751 const AbstractTypeArguments& bounds = |
| 778 AbstractTypeArguments::Handle(cls.type_parameter_extends()); | 752 AbstractTypeArguments::Handle(cls.type_parameter_bounds()); |
| 779 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || | 753 ASSERT((bounds.IsNull() && (num_type_params == 0)) || |
| 780 (extends_array.Length() == num_type_params)); | 754 (bounds.Length() == num_type_params)); |
| 781 for (intptr_t i = 0; i < num_type_params; i++) { | 755 for (intptr_t i = 0; i < num_type_params; i++) { |
| 782 type_extends = extends_array.TypeAt(i); | 756 bound = bounds.TypeAt(i); |
| 783 ResolveType(cls, type_extends); | 757 ResolveType(cls, bound); |
| 784 type_extends = FinalizeType(cls, type_extends); | 758 bound = FinalizeType(cls, bound); |
| 785 extends_array.SetTypeAt(i, type_extends); | 759 bounds.SetTypeAt(i, bound); |
| 786 } | 760 } |
| 787 } | 761 } |
| 788 | 762 |
| 789 | 763 |
| 790 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 764 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| 791 // Note that getters and setters are explicitly listed as such in the list of | 765 // Note that getters and setters are explicitly listed as such in the list of |
| 792 // functions of a class, so we do not need to consider fields as implicitly | 766 // functions of a class, so we do not need to consider fields as implicitly |
| 793 // generating getters and setters. | 767 // generating getters and setters. |
| 794 // The only compile errors we report are therefore: | 768 // The only compile errors we report are therefore: |
| 795 // - a getter having the same name as a method (but not a getter) in a super | 769 // - a getter having the same name as a method (but not a getter) in a super |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1249 va_end(args); | 1223 va_end(args); |
| 1250 if (FLAG_warning_as_error) { | 1224 if (FLAG_warning_as_error) { |
| 1251 Isolate::Current()->long_jump_base()->Jump(1, error); | 1225 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1252 UNREACHABLE(); | 1226 UNREACHABLE(); |
| 1253 } else { | 1227 } else { |
| 1254 OS::Print("%s", error.ToErrorCString()); | 1228 OS::Print("%s", error.ToErrorCString()); |
| 1255 } | 1229 } |
| 1256 } | 1230 } |
| 1257 | 1231 |
| 1258 } // namespace dart | 1232 } // namespace dart |
| OLD | NEW |