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

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

Issue 9368032: Represent declared type parameters of a class as an array of TypeParameter (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698