| 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 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 super_type_arg = super_type_arg.InstantiateFrom(arguments); | 502 super_type_arg = super_type_arg.InstantiateFrom(arguments); |
| 503 } | 503 } |
| 504 super_type_arg = super_type_arg.Canonicalize(); | 504 super_type_arg = super_type_arg.Canonicalize(); |
| 505 arguments.SetTypeAt(super_offset + i, super_type_arg); | 505 arguments.SetTypeAt(super_offset + i, super_type_arg); |
| 506 } | 506 } |
| 507 FinalizeTypeArguments(super_class, arguments); | 507 FinalizeTypeArguments(super_class, arguments); |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 | 510 |
| 511 | 511 |
| 512 // Verify the upper bounds of the type arguments of class cls. | |
| 513 void ClassFinalizer::VerifyUpperBounds(const Class& cls, | |
| 514 const AbstractTypeArguments& arguments) { | |
| 515 ASSERT(FLAG_enable_type_checks); | |
| 516 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | |
| 517 const intptr_t num_type_params = cls.NumTypeParameters(); | |
| 518 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | |
| 519 AbstractType& type = AbstractType::Handle(); | |
| 520 AbstractType& bound = AbstractType::Handle(); | |
| 521 const TypeArguments& bounds = | |
| 522 TypeArguments::Handle(cls.type_parameter_bounds()); | |
| 523 ASSERT((bounds.IsNull() && (num_type_params == 0)) || | |
| 524 (bounds.Length() == num_type_params)); | |
| 525 for (intptr_t i = 0; i < num_type_params; i++) { | |
| 526 bound = bounds.TypeAt(i); | |
| 527 if (!bound.IsDynamicType()) { | |
| 528 type = arguments.TypeAt(offset + i); | |
| 529 if (type.IsInstantiated()) { | |
| 530 if (!bound.IsInstantiated()) { | |
| 531 bound = bound.InstantiateFrom(arguments); | |
| 532 } | |
| 533 // TODO(regis): Where do we check the bound when the type is generic? | |
| 534 if (!type.IsSubtypeOf(bound)) { | |
| 535 const String& type_argument_name = String::Handle(type.Name()); | |
| 536 const String& class_name = String::Handle(cls.Name()); | |
| 537 const String& bound_name = String::Handle(bound.Name()); | |
| 538 const Script& script = Script::Handle(cls.script()); | |
| 539 ReportError(script, type.token_index(), | |
| 540 "type argument '%s' of class '%s' " | |
| 541 "does not extend bound '%s'\n", | |
| 542 type_argument_name.ToCString(), | |
| 543 class_name.ToCString(), | |
| 544 bound_name.ToCString()); | |
| 545 } | |
| 546 } | |
| 547 } | |
| 548 } | |
| 549 const Type& super_type = Type::Handle(cls.super_type()); | |
| 550 if (!super_type.IsNull()) { | |
| 551 ASSERT(super_type.IsFinalized()); | |
| 552 const Class& super_class = Class::Handle(super_type.type_class()); | |
| 553 VerifyUpperBounds(super_class, arguments); | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 | |
| 558 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 512 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
| 559 const AbstractType& type) { | 513 const AbstractType& type) { |
| 560 ASSERT(type.IsResolved()); | 514 ASSERT(type.IsResolved()); |
| 561 if (type.IsFinalized()) { | 515 if (type.IsFinalized()) { |
| 562 return type.raw(); | 516 return type.raw(); |
| 563 } | 517 } |
| 564 if (FLAG_trace_type_finalization) { | 518 if (FLAG_trace_type_finalization) { |
| 565 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); | 519 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 566 } | 520 } |
| 567 | 521 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 // FinalizeTypeArguments can modify 'full_arguments', | 625 // FinalizeTypeArguments can modify 'full_arguments', |
| 672 // canonicalize afterwards. | 626 // canonicalize afterwards. |
| 673 full_arguments ^= full_arguments.Canonicalize(); | 627 full_arguments ^= full_arguments.Canonicalize(); |
| 674 parameterized_type.set_arguments(full_arguments); | 628 parameterized_type.set_arguments(full_arguments); |
| 675 | 629 |
| 676 // Mark the type as finalized before finalizing the upper bounds, because | 630 // Mark the type as finalized before finalizing the upper bounds, because |
| 677 // cycles via upper bounds are legal at compile time. | 631 // cycles via upper bounds are legal at compile time. |
| 678 parameterized_type.set_is_finalized(); | 632 parameterized_type.set_is_finalized(); |
| 679 | 633 |
| 680 ResolveAndFinalizeUpperBounds(type_class); | 634 ResolveAndFinalizeUpperBounds(type_class); |
| 681 if (FLAG_enable_type_checks) { | 635 // No need to verify the upper bounds of the finalized type arguments, since |
| 682 VerifyUpperBounds(type_class, full_arguments); | 636 // bound errors are static type errors, which are not reported by the VM. |
| 683 } | |
| 684 } else { | 637 } else { |
| 685 parameterized_type.set_is_finalized(); | 638 parameterized_type.set_is_finalized(); |
| 686 } | 639 } |
| 687 return parameterized_type.Canonicalize(); | 640 return parameterized_type.Canonicalize(); |
| 688 } | 641 } |
| 689 | 642 |
| 690 | 643 |
| 691 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 644 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 692 const Function& function) { | 645 const Function& function) { |
| 693 // Resolve result type. | 646 // Resolve result type. |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 va_end(args); | 1177 va_end(args); |
| 1225 if (FLAG_warning_as_error) { | 1178 if (FLAG_warning_as_error) { |
| 1226 Isolate::Current()->long_jump_base()->Jump(1, error); | 1179 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1227 UNREACHABLE(); | 1180 UNREACHABLE(); |
| 1228 } else { | 1181 } else { |
| 1229 OS::Print("%s", error.ToErrorCString()); | 1182 OS::Print("%s", error.ToErrorCString()); |
| 1230 } | 1183 } |
| 1231 } | 1184 } |
| 1232 | 1185 |
| 1233 } // namespace dart | 1186 } // namespace dart |
| OLD | NEW |