| 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 #if defined (DEBUG) | 115 #if defined (DEBUG) |
| 116 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. | 116 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. |
| 117 // No cycles are allowed. | 117 // No cycles are allowed. |
| 118 void ClassFinalizer::CollectInterfaces(const Class& cls, | 118 void ClassFinalizer::CollectInterfaces(const Class& cls, |
| 119 GrowableArray<const Class*>* collected) { | 119 GrowableArray<const Class*>* collected) { |
| 120 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); | 120 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); |
| 121 for (intptr_t i = 0; i < interface_array.Length(); i++) { | 121 for (intptr_t i = 0; i < interface_array.Length(); i++) { |
| 122 Type& interface = Type::Handle(); | 122 AbstractType& interface = AbstractType::Handle(); |
| 123 interface ^= interface_array.At(i); | 123 interface ^= interface_array.At(i); |
| 124 const Class& interface_class = Class::ZoneHandle(interface.type_class()); | 124 const Class& interface_class = Class::ZoneHandle(interface.type_class()); |
| 125 collected->Add(&interface_class); | 125 collected->Add(&interface_class); |
| 126 CollectInterfaces(interface_class, collected); | 126 CollectInterfaces(interface_class, collected); |
| 127 } | 127 } |
| 128 } | 128 } |
| 129 | 129 |
| 130 | 130 |
| 131 // Collect all interfaces of the class 'cls' and check that every function | 131 // Collect all interfaces of the class 'cls' and check that every function |
| 132 // defined in each interface can be found in the class. | 132 // defined in each interface can be found in the class. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 } | 285 } |
| 286 return resolved_class.raw(); | 286 return resolved_class.raw(); |
| 287 } | 287 } |
| 288 | 288 |
| 289 | 289 |
| 290 // Resolve unresolved supertype (String -> Class). | 290 // Resolve unresolved supertype (String -> Class). |
| 291 void ClassFinalizer::ResolveSuperType(const Class& cls) { | 291 void ClassFinalizer::ResolveSuperType(const Class& cls) { |
| 292 if (cls.is_finalized()) { | 292 if (cls.is_finalized()) { |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 Type& super_type = Type::Handle(cls.super_type()); | 295 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 296 if (super_type.IsNull()) { | 296 if (super_type.IsNull()) { |
| 297 return; | 297 return; |
| 298 } | 298 } |
| 299 // Resolve failures lead to a longjmp. | 299 // Resolve failures lead to a longjmp. |
| 300 super_type = ResolveType(cls, super_type); | 300 super_type = ResolveType(cls, super_type); |
| 301 if (super_type.IsTypeParameter()) { | 301 if (super_type.IsTypeParameter()) { |
| 302 String& class_name = String::Handle(cls.Name()); | 302 String& class_name = String::Handle(cls.Name()); |
| 303 String& type_parameter_name = String::Handle(super_type.Name()); | 303 String& type_parameter_name = String::Handle(super_type.Name()); |
| 304 ReportError("'%s' cannot extend or implement type parameter '%s'.\n", | 304 ReportError("'%s' cannot extend or implement type parameter '%s'.\n", |
| 305 class_name.ToCString(), | 305 class_name.ToCString(), |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 const Script& script = Script::Handle(interface.script()); | 399 const Script& script = Script::Handle(interface.script()); |
| 400 ReportWarning(script, unresolved_factory_class.token_index(), | 400 ReportWarning(script, unresolved_factory_class.token_index(), |
| 401 "class '%s' in factory clause of interface '%s' is " | 401 "class '%s' in factory clause of interface '%s' is " |
| 402 "missing its type parameter list.\n", | 402 "missing its type parameter list.\n", |
| 403 factory_name.ToCString(), | 403 factory_name.ToCString(), |
| 404 interface_name.ToCString()); | 404 interface_name.ToCString()); |
| 405 return; | 405 return; |
| 406 } | 406 } |
| 407 String& expected_type_name = String::Handle(); | 407 String& expected_type_name = String::Handle(); |
| 408 String& actual_type_name = String::Handle(); | 408 String& actual_type_name = String::Handle(); |
| 409 Type& expected_type_extends = Type::Handle(); | 409 AbstractType& expected_type_extends = AbstractType::Handle(); |
| 410 Type& actual_type_extends = Type::Handle(); | 410 AbstractType& actual_type_extends = AbstractType::Handle(); |
| 411 const Array& expected_type_names = | 411 const Array& expected_type_names = |
| 412 Array::Handle(factory_signature_class.type_parameters()); | 412 Array::Handle(factory_signature_class.type_parameters()); |
| 413 const Array& actual_type_names = | 413 const Array& actual_type_names = |
| 414 Array::Handle(factory_class.type_parameters()); | 414 Array::Handle(factory_class.type_parameters()); |
| 415 const TypeArray& expected_extends_array = | 415 const TypeArray& expected_extends_array = |
| 416 TypeArray::Handle(factory_signature_class.type_parameter_extends()); | 416 TypeArray::Handle(factory_signature_class.type_parameter_extends()); |
| 417 const TypeArray& actual_extends_array = | 417 const TypeArray& actual_extends_array = |
| 418 TypeArray::Handle(factory_class.type_parameter_extends()); | 418 TypeArray::Handle(factory_class.type_parameter_extends()); |
| 419 for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) { | 419 for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) { |
| 420 expected_type_name ^= expected_type_names.At(i); | 420 expected_type_name ^= expected_type_names.At(i); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 436 "factory clause of interface '%s' and actual factory " | 436 "factory clause of interface '%s' and actual factory " |
| 437 "class '%s'.\n", | 437 "class '%s'.\n", |
| 438 interface_name.ToCString(), | 438 interface_name.ToCString(), |
| 439 factory_name.ToCString()); | 439 factory_name.ToCString()); |
| 440 } | 440 } |
| 441 } | 441 } |
| 442 | 442 |
| 443 | 443 |
| 444 // TODO(regis): Now that we do not resolve type parameters anymore, we could | 444 // TODO(regis): Now that we do not resolve type parameters anymore, we could |
| 445 // make this function void and resolve the type in place. | 445 // make this function void and resolve the type in place. |
| 446 RawType* ClassFinalizer::ResolveType(const Class& cls, const Type& type) { | 446 RawAbstractType* ClassFinalizer::ResolveType( |
| 447 const Class& cls, const AbstractType& type) { |
| 447 if (type.IsResolved()) { | 448 if (type.IsResolved()) { |
| 448 return type.raw(); | 449 return type.raw(); |
| 449 } | 450 } |
| 450 if (FLAG_trace_type_finalization) { | 451 if (FLAG_trace_type_finalization) { |
| 451 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 452 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 452 } | 453 } |
| 453 | 454 |
| 454 // Resolve the type class. | 455 // Resolve the type class. |
| 455 if (!type.HasResolvedTypeClass()) { | 456 if (!type.HasResolvedTypeClass()) { |
| 456 // Type parameters are always resolved in the parser in the correct | 457 // Type parameters are always resolved in the parser in the correct |
| 457 // non-static scope or factory scope. That resolution scope is unknown here. | 458 // non-static scope or factory scope. That resolution scope is unknown here. |
| 458 // Being able to resolve a type parameter from class cls here would indicate | 459 // Being able to resolve a type parameter from class cls here would indicate |
| 459 // that the type parameter appeared in a static scope. Leaving the type as | 460 // that the type parameter appeared in a static scope. Leaving the type as |
| 460 // unresolved is the correct thing to do. | 461 // unresolved is the correct thing to do. |
| 461 | 462 |
| 462 // Lookup the type class. | 463 // Lookup the type class. |
| 463 const UnresolvedClass& unresolved_class = | 464 const UnresolvedClass& unresolved_class = |
| 464 UnresolvedClass::Handle(type.unresolved_class()); | 465 UnresolvedClass::Handle(type.unresolved_class()); |
| 465 const Class& type_class = | 466 const Class& type_class = |
| 466 Class::Handle(ResolveClass(cls, unresolved_class)); | 467 Class::Handle(ResolveClass(cls, unresolved_class)); |
| 467 | 468 |
| 468 // Replace unresolved class with resolved type class. | 469 // Replace unresolved class with resolved type class. |
| 469 ASSERT(type.IsParameterizedType()); | 470 ASSERT(type.IsType()); |
| 470 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 471 Type& parameterized_type = Type::Handle(); |
| 471 parameterized_type ^= type.raw(); | 472 parameterized_type ^= type.raw(); |
| 472 parameterized_type.set_type_class(Object::Handle(type_class.raw())); | 473 parameterized_type.set_type_class(Object::Handle(type_class.raw())); |
| 473 } | 474 } |
| 474 | 475 |
| 475 // Resolve type arguments, if any. | 476 // Resolve type arguments, if any. |
| 476 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); | 477 const TypeArguments& arguments = TypeArguments::Handle(type.arguments()); |
| 477 if (!arguments.IsNull()) { | 478 if (!arguments.IsNull()) { |
| 478 intptr_t num_arguments = arguments.Length(); | 479 intptr_t num_arguments = arguments.Length(); |
| 479 Type& type_argument = Type::Handle(); | 480 AbstractType& type_argument = AbstractType::Handle(); |
| 480 for (intptr_t i = 0; i < num_arguments; i++) { | 481 for (intptr_t i = 0; i < num_arguments; i++) { |
| 481 type_argument = arguments.TypeAt(i); | 482 type_argument = arguments.TypeAt(i); |
| 482 type_argument = ResolveType(cls, type_argument); | 483 type_argument = ResolveType(cls, type_argument); |
| 483 arguments.SetTypeAt(i, type_argument); | 484 arguments.SetTypeAt(i, type_argument); |
| 484 } | 485 } |
| 485 } | 486 } |
| 486 return type.raw(); | 487 return type.raw(); |
| 487 } | 488 } |
| 488 | 489 |
| 489 | 490 |
| 490 // Finalize the type argument vector 'arguments' of the type defined by the | 491 // Finalize the type argument vector 'arguments' of the type defined by the |
| 491 // class 'cls' parameterized with the type arguments 'cls_args'. | 492 // class 'cls' parameterized with the type arguments 'cls_args'. |
| 492 // The vector 'cls_args' is already initialized as a subvector at the correct | 493 // The vector 'cls_args' is already initialized as a subvector at the correct |
| 493 // position in the passed in 'arguments' vector. | 494 // position in the passed in 'arguments' vector. |
| 494 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at | 495 // The subvector 'cls_args' has length cls.NumTypeParameters() and starts at |
| 495 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' | 496 // offset cls.NumTypeArguments() - cls.NumTypeParameters() of the 'arguments' |
| 496 // vector. | 497 // vector. |
| 497 // Example: | 498 // Example: |
| 498 // Declared: class C<K, V> extends B<V> { ... } | 499 // Declared: class C<K, V> extends B<V> { ... } |
| 499 // class B<T> extends Array<int> { ... } | 500 // class B<T> extends Array<int> { ... } |
| 500 // Input: C<String, double> expressed as | 501 // Input: C<String, double> expressed as |
| 501 // cls = C, arguments = [null, null, String, double], | 502 // cls = C, arguments = [null, null, String, double], |
| 502 // i.e. cls_args = [String, double], offset = 2, length = 2. | 503 // i.e. cls_args = [String, double], offset = 2, length = 2. |
| 503 // Output: arguments = [int, double, String, double] | 504 // Output: arguments = [int, double, String, double] |
| 504 void ClassFinalizer::FinalizeTypeArguments(const Class& cls, | 505 void ClassFinalizer::FinalizeTypeArguments(const Class& cls, |
| 505 const TypeArguments& arguments) { | 506 const TypeArguments& arguments) { |
| 506 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 507 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 507 Type& super_type = Type::Handle(cls.super_type()); | 508 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 508 if (!super_type.IsNull()) { | 509 if (!super_type.IsNull()) { |
| 509 super_type = FinalizeType(super_type); | 510 super_type = FinalizeType(super_type); |
| 510 cls.set_super_type(super_type); | 511 cls.set_super_type(super_type); |
| 511 const Class& super_class = Class::Handle(super_type.type_class()); | 512 const Class& super_class = Class::Handle(super_type.type_class()); |
| 512 const TypeArguments& super_type_args = | 513 const TypeArguments& super_type_args = |
| 513 TypeArguments::Handle(super_type.arguments()); | 514 TypeArguments::Handle(super_type.arguments()); |
| 514 const intptr_t num_super_type_params = super_class.NumTypeParameters(); | 515 const intptr_t num_super_type_params = super_class.NumTypeParameters(); |
| 515 const intptr_t offset = super_class.NumTypeArguments(); | 516 const intptr_t offset = super_class.NumTypeArguments(); |
| 516 const intptr_t super_offset = offset - num_super_type_params; | 517 const intptr_t super_offset = offset - num_super_type_params; |
| 517 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); | 518 ASSERT(offset == (cls.NumTypeArguments() - cls.NumTypeParameters())); |
| 518 Type& super_type_arg = Type::Handle(); | 519 AbstractType& super_type_arg = AbstractType::Handle(); |
| 519 for (intptr_t i = 0; i < num_super_type_params; i++) { | 520 for (intptr_t i = 0; i < num_super_type_params; i++) { |
| 520 super_type_arg = super_type_args.TypeAt(super_offset + i); | 521 super_type_arg = super_type_args.TypeAt(super_offset + i); |
| 521 if (!super_type_arg.IsInstantiated()) { | 522 if (!super_type_arg.IsInstantiated()) { |
| 522 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); | 523 super_type_arg = super_type_arg.InstantiateFrom(arguments, offset); |
| 523 } | 524 } |
| 524 super_type_arg = super_type_arg.Canonicalize(); | 525 super_type_arg = super_type_arg.Canonicalize(); |
| 525 arguments.SetTypeAt(super_offset + i, super_type_arg); | 526 arguments.SetTypeAt(super_offset + i, super_type_arg); |
| 526 } | 527 } |
| 527 FinalizeTypeArguments(super_class, arguments); | 528 FinalizeTypeArguments(super_class, arguments); |
| 528 } | 529 } |
| 529 } | 530 } |
| 530 | 531 |
| 531 | 532 |
| 532 // Verify the upper bounds of the type arguments of class cls. | 533 // Verify the upper bounds of the type arguments of class cls. |
| 533 void ClassFinalizer::VerifyUpperBounds(const Class& cls, | 534 void ClassFinalizer::VerifyUpperBounds(const Class& cls, |
| 534 const TypeArguments& arguments) { | 535 const TypeArguments& arguments) { |
| 535 ASSERT(FLAG_enable_type_checks); | 536 ASSERT(FLAG_enable_type_checks); |
| 536 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 537 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 537 const intptr_t num_type_params = cls.NumTypeParameters(); | 538 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 538 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | 539 const intptr_t offset = cls.NumTypeArguments() - num_type_params; |
| 539 Type& type = Type::Handle(); | 540 AbstractType& type = AbstractType::Handle(); |
| 540 Type& type_extends = Type::Handle(); | 541 AbstractType& type_extends = AbstractType::Handle(); |
| 541 const TypeArguments& extends_array = | 542 const TypeArguments& extends_array = |
| 542 TypeArguments::Handle(cls.type_parameter_extends()); | 543 TypeArguments::Handle(cls.type_parameter_extends()); |
| 543 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || | 544 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || |
| 544 (extends_array.Length() == num_type_params)); | 545 (extends_array.Length() == num_type_params)); |
| 545 for (intptr_t i = 0; i < num_type_params; i++) { | 546 for (intptr_t i = 0; i < num_type_params; i++) { |
| 546 type_extends = extends_array.TypeAt(i); | 547 type_extends = extends_array.TypeAt(i); |
| 547 if (!type_extends.IsDynamicType()) { | 548 if (!type_extends.IsDynamicType()) { |
| 548 type = arguments.TypeAt(offset + i); | 549 type = arguments.TypeAt(offset + i); |
| 549 if (type.IsInstantiated()) { | 550 if (type.IsInstantiated()) { |
| 550 if (!type_extends.IsInstantiated()) { | 551 if (!type_extends.IsInstantiated()) { |
| 551 type_extends = type_extends.InstantiateFrom(arguments, offset); | 552 type_extends = type_extends.InstantiateFrom(arguments, offset); |
| 552 } | 553 } |
| 553 // TODO(regis): Where do we check the constraints when the type is | 554 // TODO(regis): Where do we check the constraints when the type is |
| 554 // generic? | 555 // generic? |
| 555 if (!type.IsSubtypeOf(type_extends)) { | 556 if (!type.IsSubtypeOf(type_extends)) { |
| 556 const String& type_argument_name = String::Handle(type.Name()); | 557 const String& type_argument_name = String::Handle(type.Name()); |
| 557 const String& class_name = String::Handle(cls.Name()); | 558 const String& class_name = String::Handle(cls.Name()); |
| 558 const String& extends_name = String::Handle(type_extends.Name()); | 559 const String& extends_name = String::Handle(type_extends.Name()); |
| 559 const Script& script = Script::Handle(cls.script()); | 560 const Script& script = Script::Handle(cls.script()); |
| 560 ReportError(script, -1, | 561 ReportError(script, -1, |
| 561 "type argument '%s' of class '%s' " | 562 "type argument '%s' of class '%s' " |
| 562 "does not extend type '%s'\n", | 563 "does not extend type '%s'\n", |
| 563 type_argument_name.ToCString(), | 564 type_argument_name.ToCString(), |
| 564 class_name.ToCString(), | 565 class_name.ToCString(), |
| 565 extends_name.ToCString()); | 566 extends_name.ToCString()); |
| 566 } | 567 } |
| 567 } | 568 } |
| 568 } | 569 } |
| 569 } | 570 } |
| 570 Type& super_type = Type::Handle(cls.super_type()); | 571 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 571 if (!super_type.IsNull()) { | 572 if (!super_type.IsNull()) { |
| 572 ASSERT(super_type.IsFinalized()); | 573 ASSERT(super_type.IsFinalized()); |
| 573 const Class& super_class = Class::Handle(super_type.type_class()); | 574 const Class& super_class = Class::Handle(super_type.type_class()); |
| 574 VerifyUpperBounds(super_class, arguments); | 575 VerifyUpperBounds(super_class, arguments); |
| 575 } | 576 } |
| 576 } | 577 } |
| 577 | 578 |
| 578 | 579 |
| 579 RawType* ClassFinalizer::FinalizeType(const Type& type) { | 580 RawAbstractType* ClassFinalizer::FinalizeType(const AbstractType& type) { |
| 580 ASSERT(type.IsResolved()); | 581 ASSERT(type.IsResolved()); |
| 581 if (type.IsFinalized()) { | 582 if (type.IsFinalized()) { |
| 582 return type.raw(); | 583 return type.raw(); |
| 583 } | 584 } |
| 584 if (FLAG_trace_type_finalization) { | 585 if (FLAG_trace_type_finalization) { |
| 585 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); | 586 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 586 } | 587 } |
| 587 | 588 |
| 588 // At this point, we can only have a parameterized_type. | 589 // At this point, we can only have a parameterized_type. |
| 589 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 590 Type& parameterized_type = Type::Handle(); |
| 590 parameterized_type ^= type.raw(); | 591 parameterized_type ^= type.raw(); |
| 591 | 592 |
| 592 if (parameterized_type.IsBeingFinalized()) { | 593 if (parameterized_type.IsBeingFinalized()) { |
| 593 ReportError("type '%s' illegally refers to itself\n", | 594 ReportError("type '%s' illegally refers to itself\n", |
| 594 String::Handle(parameterized_type.Name()).ToCString()); | 595 String::Handle(parameterized_type.Name()).ToCString()); |
| 595 } | 596 } |
| 596 | 597 |
| 597 // Mark type as being finalized in order to detect illegal self reference. | 598 // Mark type as being finalized in order to detect illegal self reference. |
| 598 parameterized_type.set_is_being_finalized(); | 599 parameterized_type.set_is_being_finalized(); |
| 599 | 600 |
| 600 // Finalize the current type arguments of the type, which are still the | 601 // Finalize the current type arguments of the type, which are still the |
| 601 // parsed type arguments. | 602 // parsed type arguments. |
| 602 TypeArguments& arguments = | 603 TypeArguments& arguments = |
| 603 TypeArguments::Handle(parameterized_type.arguments()); | 604 TypeArguments::Handle(parameterized_type.arguments()); |
| 604 if (!arguments.IsNull()) { | 605 if (!arguments.IsNull()) { |
| 605 intptr_t num_arguments = arguments.Length(); | 606 intptr_t num_arguments = arguments.Length(); |
| 606 for (intptr_t i = 0; i < num_arguments; i++) { | 607 for (intptr_t i = 0; i < num_arguments; i++) { |
| 607 Type& type_argument = Type::Handle(arguments.TypeAt(i)); | 608 AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i)); |
| 608 type_argument = FinalizeType(type_argument); | 609 type_argument = FinalizeType(type_argument); |
| 609 arguments.SetTypeAt(i, type_argument); | 610 arguments.SetTypeAt(i, type_argument); |
| 610 } | 611 } |
| 611 } | 612 } |
| 612 | 613 |
| 613 // The type class does not need to be finalized in order to finalize the type, | 614 // The type class does not need to be finalized in order to finalize the type, |
| 614 // however, it must at least be resolved (this was done as part of resolving | 615 // however, it must at least be resolved (this was done as part of resolving |
| 615 // the type itself, a precondition to calling FinalizeType) and the upper | 616 // the type itself, a precondition to calling FinalizeType) and the upper |
| 616 // bounds of its type parameters must be finalized (done here). | 617 // bounds of its type parameters must be finalized (done here). |
| 617 Class& type_class = Class::Handle(parameterized_type.type_class()); | 618 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 645 } | 646 } |
| 646 // The full type argument vector consists of the type arguments of the | 647 // The full type argument vector consists of the type arguments of the |
| 647 // super types of type_class, which may be initialized from the parsed | 648 // super types of type_class, which may be initialized from the parsed |
| 648 // type arguments, followed by the parsed type arguments. | 649 // type arguments, followed by the parsed type arguments. |
| 649 if (num_type_arguments > 0) { | 650 if (num_type_arguments > 0) { |
| 650 const TypeArguments& full_arguments = TypeArguments::Handle( | 651 const TypeArguments& full_arguments = TypeArguments::Handle( |
| 651 TypeArguments::NewTypeArray(num_type_arguments)); | 652 TypeArguments::NewTypeArray(num_type_arguments)); |
| 652 // Copy the parsed type arguments at the correct offset in the full type | 653 // Copy the parsed type arguments at the correct offset in the full type |
| 653 // argument vector. | 654 // argument vector. |
| 654 const intptr_t offset = num_type_arguments - num_type_parameters; | 655 const intptr_t offset = num_type_arguments - num_type_parameters; |
| 655 Type& type = Type::Handle(Type::DynamicType()); | 656 AbstractType& type = AbstractType::Handle(Type::DynamicType()); |
| 656 for (intptr_t i = 0; i < num_type_parameters; i++) { | 657 for (intptr_t i = 0; i < num_type_parameters; i++) { |
| 657 // If no type parameters were provided, a raw type is desired, so we | 658 // If no type parameters were provided, a raw type is desired, so we |
| 658 // create a vector of DynamicType. | 659 // create a vector of DynamicType. |
| 659 if (!arguments.IsNull()) { | 660 if (!arguments.IsNull()) { |
| 660 type = arguments.TypeAt(i); | 661 type = arguments.TypeAt(i); |
| 661 } | 662 } |
| 662 full_arguments.SetTypeAt(offset + i, type); | 663 full_arguments.SetTypeAt(offset + i, type); |
| 663 } | 664 } |
| 664 if (type_class.IsSignatureClass()) { | 665 if (type_class.IsSignatureClass()) { |
| 665 const Function& signature_fun = | 666 const Function& signature_fun = |
| (...skipping 14 matching lines...) Expand all Loading... |
| 680 if (FLAG_enable_type_checks) { | 681 if (FLAG_enable_type_checks) { |
| 681 VerifyUpperBounds(type_class, full_arguments); | 682 VerifyUpperBounds(type_class, full_arguments); |
| 682 } | 683 } |
| 683 } else { | 684 } else { |
| 684 parameterized_type.set_is_finalized(); | 685 parameterized_type.set_is_finalized(); |
| 685 } | 686 } |
| 686 return parameterized_type.Canonicalize(); | 687 return parameterized_type.Canonicalize(); |
| 687 } | 688 } |
| 688 | 689 |
| 689 | 690 |
| 690 RawType* ClassFinalizer::FinalizeAndCanonicalizeType(const Type& type, | 691 RawAbstractType* ClassFinalizer::FinalizeAndCanonicalizeType( |
| 691 String* errmsg) { | 692 const AbstractType& type, String* errmsg) { |
| 692 Isolate* isolate = Isolate::Current(); | 693 Isolate* isolate = Isolate::Current(); |
| 693 ASSERT(isolate != NULL); | 694 ASSERT(isolate != NULL); |
| 694 LongJump* base = isolate->long_jump_base(); | 695 LongJump* base = isolate->long_jump_base(); |
| 695 LongJump jump; | 696 LongJump jump; |
| 696 isolate->set_long_jump_base(&jump); | 697 isolate->set_long_jump_base(&jump); |
| 697 if (setjmp(*jump.Set()) == 0) { | 698 if (setjmp(*jump.Set()) == 0) { |
| 698 const Type& canonical_type = Type::Handle(FinalizeType(type)); | 699 const AbstractType& canonical_type = |
| 700 AbstractType::Handle(FinalizeType(type)); |
| 699 isolate->set_long_jump_base(base); | 701 isolate->set_long_jump_base(base); |
| 700 *errmsg = String::null(); | 702 *errmsg = String::null(); |
| 701 return canonical_type.raw(); | 703 return canonical_type.raw(); |
| 702 } else { | 704 } else { |
| 703 // Error occured: Get the error message. | 705 // Error occured: Get the error message. |
| 704 isolate->set_long_jump_base(base); | 706 isolate->set_long_jump_base(base); |
| 705 *errmsg = isolate->object_store()->sticky_error(); | 707 *errmsg = isolate->object_store()->sticky_error(); |
| 706 return type.raw(); | 708 return type.raw(); |
| 707 } | 709 } |
| 708 UNREACHABLE(); | 710 UNREACHABLE(); |
| 709 return NULL; | 711 return NULL; |
| 710 } | 712 } |
| 711 | 713 |
| 712 | 714 |
| 713 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 715 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 714 const Function& function) { | 716 const Function& function) { |
| 715 // Resolve result type. | 717 // Resolve result type. |
| 716 Type& type = Type::Handle(function.result_type()); | 718 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 717 if (!type.IsResolved()) { | 719 if (!type.IsResolved()) { |
| 718 if (function.IsFactory()) { | 720 if (function.IsFactory()) { |
| 719 // The signature class of the factory for a generic class holds the type | 721 // The signature class of the factory for a generic class holds the type |
| 720 // parameters and their upper bounds. Copy the signature class from the | 722 // parameters and their upper bounds. Copy the signature class from the |
| 721 // result before it gets resolved. | 723 // result before it gets resolved. |
| 722 const UnresolvedClass& unresolved_type_class = | 724 const UnresolvedClass& unresolved_type_class = |
| 723 UnresolvedClass::Handle(type.unresolved_class()); | 725 UnresolvedClass::Handle(type.unresolved_class()); |
| 724 const Class& factory_signature_class = | 726 const Class& factory_signature_class = |
| 725 Class::Handle(unresolved_type_class.factory_signature_class()); | 727 Class::Handle(unresolved_type_class.factory_signature_class()); |
| 726 ASSERT(!factory_signature_class.IsNull()); | 728 ASSERT(!factory_signature_class.IsNull()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 } | 814 } |
| 813 super_class = super_class.SuperClass(); | 815 super_class = super_class.SuperClass(); |
| 814 } | 816 } |
| 815 return Class::null(); | 817 return Class::null(); |
| 816 } | 818 } |
| 817 | 819 |
| 818 | 820 |
| 819 // Resolve and finalize the upper bounds of the type parameters of class cls. | 821 // Resolve and finalize the upper bounds of the type parameters of class cls. |
| 820 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { | 822 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { |
| 821 const intptr_t num_type_params = cls.NumTypeParameters(); | 823 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 822 Type& type_extends = Type::Handle(); | 824 AbstractType& type_extends = AbstractType::Handle(); |
| 823 const TypeArguments& extends_array = | 825 const TypeArguments& extends_array = |
| 824 TypeArguments::Handle(cls.type_parameter_extends()); | 826 TypeArguments::Handle(cls.type_parameter_extends()); |
| 825 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || | 827 ASSERT((extends_array.IsNull() && (num_type_params == 0)) || |
| 826 (extends_array.Length() == num_type_params)); | 828 (extends_array.Length() == num_type_params)); |
| 827 for (intptr_t i = 0; i < num_type_params; i++) { | 829 for (intptr_t i = 0; i < num_type_params; i++) { |
| 828 type_extends = extends_array.TypeAt(i); | 830 type_extends = extends_array.TypeAt(i); |
| 829 type_extends = ResolveType(cls, type_extends); | 831 type_extends = ResolveType(cls, type_extends); |
| 830 extends_array.SetTypeAt(i, type_extends); | 832 extends_array.SetTypeAt(i, type_extends); |
| 831 type_extends = FinalizeType(type_extends); | 833 type_extends = FinalizeType(type_extends); |
| 832 extends_array.SetTypeAt(i, type_extends); | 834 extends_array.SetTypeAt(i, type_extends); |
| 833 } | 835 } |
| 834 } | 836 } |
| 835 | 837 |
| 836 | 838 |
| 837 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 839 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| 838 // Note that getters and setters are explicitly listed as such in the list of | 840 // Note that getters and setters are explicitly listed as such in the list of |
| 839 // functions of a class, so we do not need to consider fields as implicitly | 841 // functions of a class, so we do not need to consider fields as implicitly |
| 840 // generating getters and setters. | 842 // generating getters and setters. |
| 841 // The only compile errors we report are therefore: | 843 // The only compile errors we report are therefore: |
| 842 // - a getter having the same name as a method (but not a getter) in a super | 844 // - a getter having the same name as a method (but not a getter) in a super |
| 843 // class or in a subclass. | 845 // class or in a subclass. |
| 844 // - a setter having the same name as a method (but not a setter) in a super | 846 // - a setter having the same name as a method (but not a setter) in a super |
| 845 // class or in a subclass. | 847 // class or in a subclass. |
| 846 // - a static field, instance field, or static method (but not an instance | 848 // - a static field, instance field, or static method (but not an instance |
| 847 // method) having the same name as an instance member in a super class. | 849 // method) having the same name as an instance member in a super class. |
| 848 | 850 |
| 849 // Resolve type of fields and check for conflicts in super classes. | 851 // Resolve type of fields and check for conflicts in super classes. |
| 850 Array& array = Array::Handle(cls.fields()); | 852 Array& array = Array::Handle(cls.fields()); |
| 851 Field& field = Field::Handle(); | 853 Field& field = Field::Handle(); |
| 852 Type& type = Type::Handle(); | 854 AbstractType& type = AbstractType::Handle(); |
| 853 String& name = String::Handle(); | 855 String& name = String::Handle(); |
| 854 Class& super_class = Class::Handle(); | 856 Class& super_class = Class::Handle(); |
| 855 intptr_t num_fields = array.Length(); | 857 intptr_t num_fields = array.Length(); |
| 856 for (intptr_t i = 0; i < num_fields; i++) { | 858 for (intptr_t i = 0; i < num_fields; i++) { |
| 857 field ^= array.At(i); | 859 field ^= array.At(i); |
| 858 type = field.type(); | 860 type = field.type(); |
| 859 type = ResolveType(cls, type); | 861 type = ResolveType(cls, type); |
| 860 field.set_type(type); | 862 field.set_type(type); |
| 861 type = FinalizeType(type); | 863 type = FinalizeType(type); |
| 862 field.set_type(type); | 864 field.set_type(type); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 995 ASSERT(!cls.IsSignatureClass()); | 997 ASSERT(!cls.IsSignatureClass()); |
| 996 if (!IsSuperCycleFree(cls)) { | 998 if (!IsSuperCycleFree(cls)) { |
| 997 const String& name = String::Handle(cls.Name()); | 999 const String& name = String::Handle(cls.Name()); |
| 998 const Script& script = Script::Handle(cls.script()); | 1000 const Script& script = Script::Handle(cls.script()); |
| 999 ReportError(script, -1, | 1001 ReportError(script, -1, |
| 1000 "class '%s' has a cycle in its superclass relationship.\n", | 1002 "class '%s' has a cycle in its superclass relationship.\n", |
| 1001 name.ToCString()); | 1003 name.ToCString()); |
| 1002 } | 1004 } |
| 1003 GrowableArray<const Class*> visited; | 1005 GrowableArray<const Class*> visited; |
| 1004 ResolveInterfaces(cls, &visited); | 1006 ResolveInterfaces(cls, &visited); |
| 1005 Type& super_type = Type::Handle(cls.super_type()); | 1007 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 1006 if (!super_type.IsNull()) { | 1008 if (!super_type.IsNull()) { |
| 1007 const Class& super_class = Class::Handle(super_type.type_class()); | 1009 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1008 // Finalize super class and super type. | 1010 // Finalize super class and super type. |
| 1009 FinalizeClass(super_class, generating_snapshot); | 1011 FinalizeClass(super_class, generating_snapshot); |
| 1010 super_type = FinalizeType(super_type); | 1012 super_type = FinalizeType(super_type); |
| 1011 cls.set_super_type(super_type); | 1013 cls.set_super_type(super_type); |
| 1012 } | 1014 } |
| 1013 if (cls.is_interface()) { | 1015 if (cls.is_interface()) { |
| 1014 if (cls.HasFactoryClass()) { | 1016 if (cls.HasFactoryClass()) { |
| 1015 const Class& factory_class = Class::Handle(cls.FactoryClass()); | 1017 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
| 1016 // Finalize factory class. | 1018 // Finalize factory class. |
| 1017 if (!factory_class.is_finalized()) { | 1019 if (!factory_class.is_finalized()) { |
| 1018 FinalizeClass(factory_class, generating_snapshot); | 1020 FinalizeClass(factory_class, generating_snapshot); |
| 1019 // Finalizing the factory class may indirectly finalize this interface. | 1021 // Finalizing the factory class may indirectly finalize this interface. |
| 1020 if (cls.is_finalized()) { | 1022 if (cls.is_finalized()) { |
| 1021 return; | 1023 return; |
| 1022 } | 1024 } |
| 1023 } | 1025 } |
| 1024 } | 1026 } |
| 1025 } | 1027 } |
| 1026 // Finalize interface types (but not necessarily interface classes). | 1028 // Finalize interface types (but not necessarily interface classes). |
| 1027 Array& interface_types = Array::Handle(cls.interfaces()); | 1029 Array& interface_types = Array::Handle(cls.interfaces()); |
| 1028 Type& interface_type = Type::Handle(); | 1030 AbstractType& interface_type = AbstractType::Handle(); |
| 1029 for (intptr_t i = 0; i < interface_types.Length(); i++) { | 1031 for (intptr_t i = 0; i < interface_types.Length(); i++) { |
| 1030 interface_type ^= interface_types.At(i); | 1032 interface_type ^= interface_types.At(i); |
| 1031 interface_type = FinalizeType(interface_type); | 1033 interface_type = FinalizeType(interface_type); |
| 1032 interface_types.SetAt(i, interface_type); | 1034 interface_types.SetAt(i, interface_type); |
| 1033 } | 1035 } |
| 1034 // Mark as finalized before resolving type parameter upper bounds and member | 1036 // Mark as finalized before resolving type parameter upper bounds and member |
| 1035 // types in order to break cycles. | 1037 // types in order to break cycles. |
| 1036 cls.Finalize(); | 1038 cls.Finalize(); |
| 1037 ResolveAndFinalizeUpperBounds(cls); | 1039 ResolveAndFinalizeUpperBounds(cls); |
| 1038 ResolveAndFinalizeMemberTypes(cls); | 1040 ResolveAndFinalizeMemberTypes(cls); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 test2 = test2.SuperClass(); | 1074 test2 = test2.SuperClass(); |
| 1073 if (!test2.IsNull()) { | 1075 if (!test2.IsNull()) { |
| 1074 test2 = test2.SuperClass(); | 1076 test2 = test2.SuperClass(); |
| 1075 } | 1077 } |
| 1076 } | 1078 } |
| 1077 // No cycles. | 1079 // No cycles. |
| 1078 return true; | 1080 return true; |
| 1079 } | 1081 } |
| 1080 | 1082 |
| 1081 | 1083 |
| 1082 bool ClassFinalizer::AddInterfaceIfUnique(GrowableArray<Type*>* interface_list, | 1084 bool ClassFinalizer::AddInterfaceIfUnique( |
| 1083 Type* interface, | 1085 GrowableArray<AbstractType*>* interface_list, |
| 1084 Type* conflicting) { | 1086 AbstractType* interface, |
| 1087 AbstractType* conflicting) { |
| 1085 String& interface_class_name = String::Handle(interface->ClassName()); | 1088 String& interface_class_name = String::Handle(interface->ClassName()); |
| 1086 String& existing_interface_class_name = String::Handle(); | 1089 String& existing_interface_class_name = String::Handle(); |
| 1087 for (intptr_t i = 0; i < interface_list->length(); i++) { | 1090 for (intptr_t i = 0; i < interface_list->length(); i++) { |
| 1088 existing_interface_class_name = (*interface_list)[i]->ClassName(); | 1091 existing_interface_class_name = (*interface_list)[i]->ClassName(); |
| 1089 if (interface_class_name.Equals(existing_interface_class_name)) { | 1092 if (interface_class_name.Equals(existing_interface_class_name)) { |
| 1090 // Same interface class name, now check names of type arguments. | 1093 // Same interface class name, now check names of type arguments. |
| 1091 const String& interface_name = String::Handle(interface->Name()); | 1094 const String& interface_name = String::Handle(interface->Name()); |
| 1092 const String& existing_interface_name = | 1095 const String& existing_interface_name = |
| 1093 String::Handle((*interface_list)[i]->Name()); | 1096 String::Handle((*interface_list)[i]->Name()); |
| 1094 // TODO(regis): Revisit depending on the outcome of issue 4905685. | 1097 // TODO(regis): Revisit depending on the outcome of issue 4905685. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 } | 1146 } |
| 1144 | 1147 |
| 1145 // If cls belongs to core lib or to core lib's implementation, restrictions | 1148 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 1146 // about allowed interfaces are lifted. | 1149 // about allowed interfaces are lifted. |
| 1147 const bool cls_belongs_to_core_lib = | 1150 const bool cls_belongs_to_core_lib = |
| 1148 (cls.library() == Library::CoreLibrary()) || | 1151 (cls.library() == Library::CoreLibrary()) || |
| 1149 (cls.library() == Library::CoreImplLibrary()); | 1152 (cls.library() == Library::CoreImplLibrary()); |
| 1150 | 1153 |
| 1151 // Resolve and check the interfaces of cls. | 1154 // Resolve and check the interfaces of cls. |
| 1152 visited->Add(&cls); | 1155 visited->Add(&cls); |
| 1153 Type& interface = Type::Handle(); | 1156 AbstractType& interface = AbstractType::Handle(); |
| 1154 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 1157 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 1155 interface ^= super_interfaces.At(i); | 1158 interface ^= super_interfaces.At(i); |
| 1156 interface = ResolveType(cls, interface); | 1159 interface = ResolveType(cls, interface); |
| 1157 super_interfaces.SetAt(i, interface); | 1160 super_interfaces.SetAt(i, interface); |
| 1158 if (interface.IsTypeParameter()) { | 1161 if (interface.IsTypeParameter()) { |
| 1159 const Script& script = Script::Handle(cls.script()); | 1162 const Script& script = Script::Handle(cls.script()); |
| 1160 ReportError(script, -1, | 1163 ReportError(script, -1, |
| 1161 "Type parameter '%s' cannot be used as interface\n", | 1164 "Type parameter '%s' cannot be used as interface\n", |
| 1162 String::Handle(interface.Name()).ToCString()); | 1165 String::Handle(interface.Name()).ToCString()); |
| 1163 } | 1166 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1233 class_name.ToCString()); | 1236 class_name.ToCString()); |
| 1234 const Library& library = Library::Handle(cls.library()); | 1237 const Library& library = Library::Handle(cls.library()); |
| 1235 if (!library.IsNull()) { | 1238 if (!library.IsNull()) { |
| 1236 OS::Print(" library '%s%s':\n", | 1239 OS::Print(" library '%s%s':\n", |
| 1237 String::Handle(library.url()).ToCString(), | 1240 String::Handle(library.url()).ToCString(), |
| 1238 String::Handle(library.private_key()).ToCString()); | 1241 String::Handle(library.private_key()).ToCString()); |
| 1239 } else { | 1242 } else { |
| 1240 OS::Print(" (null library):\n"); | 1243 OS::Print(" (null library):\n"); |
| 1241 } | 1244 } |
| 1242 const Array& interfaces_array = Array::Handle(cls.interfaces()); | 1245 const Array& interfaces_array = Array::Handle(cls.interfaces()); |
| 1243 Type& interface = Type::Handle(); | 1246 AbstractType& interface = AbstractType::Handle(); |
| 1244 intptr_t len = interfaces_array.Length(); | 1247 intptr_t len = interfaces_array.Length(); |
| 1245 for (intptr_t i = 0; i < len; i++) { | 1248 for (intptr_t i = 0; i < len; i++) { |
| 1246 interface ^= interfaces_array.At(i); | 1249 interface ^= interfaces_array.At(i); |
| 1247 OS::Print(" %s\n", interface.ToCString()); | 1250 OS::Print(" %s\n", interface.ToCString()); |
| 1248 } | 1251 } |
| 1249 const Array& functions_array = Array::Handle(cls.functions()); | 1252 const Array& functions_array = Array::Handle(cls.functions()); |
| 1250 Function& function = Function::Handle(); | 1253 Function& function = Function::Handle(); |
| 1251 len = functions_array.Length(); | 1254 len = functions_array.Length(); |
| 1252 for (intptr_t i = 0; i < len; i++) { | 1255 for (intptr_t i = 0; i < len; i++) { |
| 1253 function ^= functions_array.At(i); | 1256 function ^= functions_array.At(i); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 va_end(args); | 1309 va_end(args); |
| 1307 if (FLAG_warning_as_error) { | 1310 if (FLAG_warning_as_error) { |
| 1308 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 1311 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 1309 UNREACHABLE(); | 1312 UNREACHABLE(); |
| 1310 } else { | 1313 } else { |
| 1311 OS::Print(message_buffer); | 1314 OS::Print(message_buffer); |
| 1312 } | 1315 } |
| 1313 } | 1316 } |
| 1314 | 1317 |
| 1315 } // namespace dart | 1318 } // namespace dart |
| OLD | NEW |