| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 ASSERT(factory.RedirectionTarget() == Function::null()); | 340 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 341 return; | 341 return; |
| 342 } | 342 } |
| 343 ASSERT(!type.IsTypeParameter()); // Resolved in parser. | 343 ASSERT(!type.IsTypeParameter()); // Resolved in parser. |
| 344 if (type.IsDynamicType()) { | 344 if (type.IsDynamicType()) { |
| 345 // Replace the type with a malformed type and compile a throw when called. | 345 // Replace the type with a malformed type and compile a throw when called. |
| 346 type = NewFinalizedMalformedType( | 346 type = NewFinalizedMalformedType( |
| 347 Error::Handle(), // No previous error. | 347 Error::Handle(), // No previous error. |
| 348 cls, | 348 cls, |
| 349 factory.token_pos(), | 349 factory.token_pos(), |
| 350 kResolveTypeParameters, // No compile-time error. | |
| 351 "factory may not redirect to 'dynamic'"); | 350 "factory may not redirect to 'dynamic'"); |
| 352 factory.SetRedirectionType(type); | 351 factory.SetRedirectionType(type); |
| 353 ASSERT(factory.RedirectionTarget() == Function::null()); | 352 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 354 return; | 353 return; |
| 355 } | 354 } |
| 356 const Class& target_class = Class::Handle(type.type_class()); | 355 const Class& target_class = Class::Handle(type.type_class()); |
| 357 String& target_class_name = String::Handle(target_class.Name()); | 356 String& target_class_name = String::Handle(target_class.Name()); |
| 358 String& target_name = String::Handle( | 357 String& target_name = String::Handle( |
| 359 String::Concat(target_class_name, Symbols::Dot())); | 358 String::Concat(target_class_name, Symbols::Dot())); |
| 360 const String& identifier = String::Handle(factory.RedirectionIdentifier()); | 359 const String& identifier = String::Handle(factory.RedirectionIdentifier()); |
| 361 if (!identifier.IsNull()) { | 360 if (!identifier.IsNull()) { |
| 362 target_name = String::Concat(target_name, identifier); | 361 target_name = String::Concat(target_name, identifier); |
| 363 } | 362 } |
| 364 | 363 |
| 365 // Verify that the target constructor of the redirection exists. | 364 // Verify that the target constructor of the redirection exists. |
| 366 target = target_class.LookupConstructor(target_name); | 365 target = target_class.LookupConstructor(target_name); |
| 367 if (target.IsNull()) { | 366 if (target.IsNull()) { |
| 368 target = target_class.LookupFactory(target_name); | 367 target = target_class.LookupFactory(target_name); |
| 369 } | 368 } |
| 370 if (target.IsNull()) { | 369 if (target.IsNull()) { |
| 371 const String& user_visible_target_name = | 370 const String& user_visible_target_name = |
| 372 identifier.IsNull() ? target_class_name : target_name; | 371 identifier.IsNull() ? target_class_name : target_name; |
| 373 // Replace the type with a malformed type and compile a throw when called. | 372 // Replace the type with a malformed type and compile a throw when called. |
| 374 type = NewFinalizedMalformedType( | 373 type = NewFinalizedMalformedType( |
| 375 Error::Handle(), // No previous error. | 374 Error::Handle(), // No previous error. |
| 376 cls, | 375 cls, |
| 377 factory.token_pos(), | 376 factory.token_pos(), |
| 378 kResolveTypeParameters, // No compile-time error. | |
| 379 "class '%s' has no constructor or factory named '%s'", | 377 "class '%s' has no constructor or factory named '%s'", |
| 380 target_class_name.ToCString(), | 378 target_class_name.ToCString(), |
| 381 user_visible_target_name.ToCString()); | 379 user_visible_target_name.ToCString()); |
| 382 factory.SetRedirectionType(type); | 380 factory.SetRedirectionType(type); |
| 383 ASSERT(factory.RedirectionTarget() == Function::null()); | 381 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 384 return; | 382 return; |
| 385 } | 383 } |
| 386 | 384 |
| 387 // Verify that the target is compatible with the redirecting factory. | 385 // Verify that the target is compatible with the redirecting factory. |
| 388 if (!target.HasCompatibleParametersWith(factory)) { | 386 if (!target.HasCompatibleParametersWith(factory)) { |
| 389 type = NewFinalizedMalformedType( | 387 type = NewFinalizedMalformedType( |
| 390 Error::Handle(), // No previous error. | 388 Error::Handle(), // No previous error. |
| 391 cls, | 389 cls, |
| 392 factory.token_pos(), | 390 factory.token_pos(), |
| 393 kResolveTypeParameters, // No compile-time error. | |
| 394 "constructor '%s' has incompatible parameters with " | 391 "constructor '%s' has incompatible parameters with " |
| 395 "redirecting factory '%s'", | 392 "redirecting factory '%s'", |
| 396 String::Handle(target.name()).ToCString(), | 393 String::Handle(target.name()).ToCString(), |
| 397 String::Handle(factory.name()).ToCString()); | 394 String::Handle(factory.name()).ToCString()); |
| 398 factory.SetRedirectionType(type); | 395 factory.SetRedirectionType(type); |
| 399 ASSERT(factory.RedirectionTarget() == Function::null()); | 396 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 400 return; | 397 return; |
| 401 } | 398 } |
| 402 | 399 |
| 403 // Verify that the target is const if the redirecting factory is const. | 400 // Verify that the target is const if the redirecting factory is const. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 430 // If the target type refers to type parameters, substitute them with the | 427 // If the target type refers to type parameters, substitute them with the |
| 431 // type arguments of the redirection type. | 428 // type arguments of the redirection type. |
| 432 if (!target_type.IsInstantiated()) { | 429 if (!target_type.IsInstantiated()) { |
| 433 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( | 430 const AbstractTypeArguments& type_args = AbstractTypeArguments::Handle( |
| 434 type.arguments()); | 431 type.arguments()); |
| 435 Error& malformed_error = Error::Handle(); | 432 Error& malformed_error = Error::Handle(); |
| 436 target_type ^= target_type.InstantiateFrom(type_args, &malformed_error); | 433 target_type ^= target_type.InstantiateFrom(type_args, &malformed_error); |
| 437 if (malformed_error.IsNull()) { | 434 if (malformed_error.IsNull()) { |
| 438 target_type ^= FinalizeType(cls, target_type, kCanonicalize); | 435 target_type ^= FinalizeType(cls, target_type, kCanonicalize); |
| 439 } else { | 436 } else { |
| 440 FinalizeMalformedType(malformed_error, | 437 FinalizeMalformedType(malformed_error, cls, target_type, |
| 441 cls, target_type, kFinalize, | |
| 442 "cannot resolve redirecting factory"); | 438 "cannot resolve redirecting factory"); |
| 443 target_target = Function::null(); | 439 target_target = Function::null(); |
| 444 } | 440 } |
| 445 } | 441 } |
| 446 } | 442 } |
| 447 factory.SetRedirectionType(target_type); | 443 factory.SetRedirectionType(target_type); |
| 448 factory.SetRedirectionTarget(target_target); | 444 factory.SetRedirectionTarget(target_target); |
| 449 } | 445 } |
| 450 | 446 |
| 451 | 447 |
| 452 void ClassFinalizer::ResolveType(const Class& cls, | 448 void ClassFinalizer::ResolveType(const Class& cls, |
| 453 const AbstractType& type, | 449 const AbstractType& type, |
| 454 FinalizationKind finalization) { | 450 FinalizationKind finalization) { |
| 455 if (type.IsResolved() || type.IsFinalized()) { | 451 if (type.IsResolved() || type.IsFinalized()) { |
| 456 if ((finalization == kCanonicalizeWellFormed) && type.IsMalformed()) { | |
| 457 ReportError(Error::Handle(type.malformed_error())); | |
| 458 } | |
| 459 return; | 452 return; |
| 460 } | 453 } |
| 461 if (FLAG_trace_type_finalization) { | 454 if (FLAG_trace_type_finalization) { |
| 462 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 455 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 463 } | 456 } |
| 464 | 457 |
| 465 // Resolve the type class. | 458 // Resolve the type class. |
| 466 if (!type.HasResolvedTypeClass()) { | 459 if (!type.HasResolvedTypeClass()) { |
| 467 // Type parameters are always resolved in the parser in the correct | 460 // Type parameters are always resolved in the parser in the correct |
| 468 // non-static scope or factory scope. That resolution scope is unknown here. | 461 // non-static scope or factory scope. That resolution scope is unknown here. |
| 469 // Being able to resolve a type parameter from class cls here would indicate | 462 // Being able to resolve a type parameter from class cls here would indicate |
| 470 // that the type parameter appeared in a static scope. Leaving the type as | 463 // that the type parameter appeared in a static scope. Leaving the type as |
| 471 // unresolved is the correct thing to do. | 464 // unresolved is the correct thing to do. |
| 472 | 465 |
| 473 // Lookup the type class. | 466 // Lookup the type class. |
| 474 const UnresolvedClass& unresolved_class = | 467 const UnresolvedClass& unresolved_class = |
| 475 UnresolvedClass::Handle(type.unresolved_class()); | 468 UnresolvedClass::Handle(type.unresolved_class()); |
| 476 Error& ambiguous_error = Error::Handle(); | 469 Error& ambiguous_error = Error::Handle(); |
| 477 const Class& type_class = | 470 const Class& type_class = |
| 478 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error)); | 471 Class::Handle(ResolveClass(cls, unresolved_class, &ambiguous_error)); |
| 479 | 472 |
| 480 // Replace unresolved class with resolved type class. | 473 // Replace unresolved class with resolved type class. |
| 481 const Type& parameterized_type = Type::Cast(type); | 474 const Type& parameterized_type = Type::Cast(type); |
| 482 if (!type_class.IsNull()) { | 475 if (type_class.IsNull()) { |
| 483 parameterized_type.set_type_class(type_class); | 476 if ((finalization == kCanonicalizeWellFormed) || |
| 484 } else { | 477 FLAG_error_on_malformed_type) { |
| 485 // The type class could not be resolved. The type is malformed. | 478 // The type class could not be resolved. The type is malformed. |
| 486 FinalizeMalformedType(ambiguous_error, // May be null. | 479 FinalizeMalformedType( |
| 487 cls, parameterized_type, finalization, | 480 ambiguous_error, // May be null. |
| 488 "cannot resolve class name '%s' from '%s'", | 481 cls, |
| 489 String::Handle(unresolved_class.Name()).ToCString(), | 482 parameterized_type, |
| 490 String::Handle(cls.Name()).ToCString()); | 483 "cannot resolve class '%s' from '%s'", |
| 484 String::Handle(unresolved_class.Name()).ToCString(), |
| 485 String::Handle(cls.Name()).ToCString()); |
| 486 } else { |
| 487 // Map the malformed type to dynamic and ignore type arguments. |
| 488 parameterized_type.set_type_class(Class::Handle( |
| 489 Object::dynamic_class())); |
| 490 parameterized_type.set_arguments( |
| 491 Object::null_abstract_type_arguments()); |
| 492 } |
| 491 return; | 493 return; |
| 492 } | 494 } |
| 495 parameterized_type.set_type_class(type_class); |
| 493 } | 496 } |
| 494 | 497 |
| 495 // Resolve type arguments, if any. | 498 // Resolve type arguments, if any. |
| 496 const AbstractTypeArguments& arguments = | 499 const AbstractTypeArguments& arguments = |
| 497 AbstractTypeArguments::Handle(type.arguments()); | 500 AbstractTypeArguments::Handle(type.arguments()); |
| 498 if (!arguments.IsNull()) { | 501 if (!arguments.IsNull()) { |
| 499 intptr_t num_arguments = arguments.Length(); | 502 intptr_t num_arguments = arguments.Length(); |
| 500 AbstractType& type_argument = AbstractType::Handle(); | 503 AbstractType& type_argument = AbstractType::Handle(); |
| 501 for (intptr_t i = 0; i < num_arguments; i++) { | 504 for (intptr_t i = 0; i < num_arguments; i++) { |
| 502 type_argument = arguments.TypeAt(i); | 505 type_argument = arguments.TypeAt(i); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 } | 704 } |
| 702 } | 705 } |
| 703 | 706 |
| 704 | 707 |
| 705 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 708 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
| 706 const AbstractType& type, | 709 const AbstractType& type, |
| 707 FinalizationKind finalization) { | 710 FinalizationKind finalization) { |
| 708 if (type.IsFinalized()) { | 711 if (type.IsFinalized()) { |
| 709 // Ensure type is canonical if canonicalization is requested, unless type is | 712 // Ensure type is canonical if canonicalization is requested, unless type is |
| 710 // malformed. | 713 // malformed. |
| 711 if (finalization >= kCanonicalize) { | 714 if ((finalization >= kCanonicalize) && !type.IsMalformed()) { |
| 712 if (type.IsMalformed()) { | 715 return type.Canonicalize(); |
| 713 if (finalization == kCanonicalizeWellFormed) { | |
| 714 ReportError(Error::Handle(type.malformed_error())); | |
| 715 } | |
| 716 } else { | |
| 717 return type.Canonicalize(); | |
| 718 } | |
| 719 } | 716 } |
| 720 return type.raw(); | 717 return type.raw(); |
| 721 } | 718 } |
| 722 ASSERT(type.IsResolved()); | 719 ASSERT(type.IsResolved()); |
| 723 ASSERT(finalization >= kFinalize); | 720 ASSERT(finalization >= kFinalize); |
| 724 | 721 |
| 725 if (FLAG_trace_type_finalization) { | 722 if (FLAG_trace_type_finalization) { |
| 726 OS::Print("Finalize type '%s' for class '%s'\n", | 723 OS::Print("Finalize type '%s' for class '%s'\n", |
| 727 String::Handle(type.Name()).ToCString(), | 724 String::Handle(type.Name()).ToCString(), |
| 728 cls.ToCString()); | 725 cls.ToCString()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 742 parameterized_class.NumTypeParameters(); | 739 parameterized_class.NumTypeParameters(); |
| 743 type_parameter.set_index(type_parameter.index() + offset); | 740 type_parameter.set_index(type_parameter.index() + offset); |
| 744 type_parameter.set_is_finalized(); | 741 type_parameter.set_is_finalized(); |
| 745 // We do not canonicalize type parameters. | 742 // We do not canonicalize type parameters. |
| 746 return type_parameter.raw(); | 743 return type_parameter.raw(); |
| 747 } | 744 } |
| 748 | 745 |
| 749 // At this point, we can only have a parameterized_type. | 746 // At this point, we can only have a parameterized_type. |
| 750 const Type& parameterized_type = Type::Cast(type); | 747 const Type& parameterized_type = Type::Cast(type); |
| 751 | 748 |
| 752 if (parameterized_type.IsBeingFinalized()) { | 749 // Types illegally referring to themselves should have been detected earlier. |
| 753 // Self reference detected. The type is malformed. | 750 ASSERT(!parameterized_type.IsBeingFinalized()); |
| 754 FinalizeMalformedType( | |
| 755 Error::Handle(), // No previous error. | |
| 756 cls, parameterized_type, finalization, | |
| 757 "type '%s' illegally refers to itself", | |
| 758 String::Handle(parameterized_type.UserVisibleName()).ToCString()); | |
| 759 return parameterized_type.raw(); | |
| 760 } | |
| 761 | 751 |
| 762 // Mark type as being finalized in order to detect illegal self reference. | 752 // Mark type as being finalized in order to detect illegal self reference. |
| 763 parameterized_type.set_is_being_finalized(); | 753 parameterized_type.set_is_being_finalized(); |
| 764 | 754 |
| 765 // The type class does not need to be finalized in order to finalize the type, | 755 // The type class does not need to be finalized in order to finalize the type, |
| 766 // however, it must at least be resolved (this was done as part of resolving | 756 // however, it must at least be resolved (this was done as part of resolving |
| 767 // the type itself, a precondition to calling FinalizeType). | 757 // the type itself, a precondition to calling FinalizeType). |
| 768 // Also, the interfaces of the type class must be resolved and the type | 758 // Also, the interfaces of the type class must be resolved and the type |
| 769 // parameters of the type class must be finalized. | 759 // parameters of the type class must be finalized. |
| 770 Class& type_class = Class::Handle(parameterized_type.type_class()); | 760 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| 771 if (!type_class.is_type_finalized()) { | 761 if (!type_class.is_type_finalized()) { |
| 772 FinalizeTypeParameters(type_class); | 762 FinalizeTypeParameters(type_class); |
| 773 ResolveUpperBounds(type_class); | 763 ResolveUpperBounds(type_class); |
| 774 } | 764 } |
| 775 | 765 |
| 776 // Finalize the current type arguments of the type, which are still the | 766 // Finalize the current type arguments of the type, which are still the |
| 777 // parsed type arguments. | 767 // parsed type arguments. |
| 778 AbstractTypeArguments& arguments = | 768 AbstractTypeArguments& arguments = |
| 779 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 769 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
| 780 if (!arguments.IsNull()) { | 770 if (!arguments.IsNull()) { |
| 781 intptr_t num_arguments = arguments.Length(); | 771 intptr_t num_arguments = arguments.Length(); |
| 782 AbstractType& type_argument = AbstractType::Handle(); | 772 AbstractType& type_argument = AbstractType::Handle(); |
| 783 for (intptr_t i = 0; i < num_arguments; i++) { | 773 for (intptr_t i = 0; i < num_arguments; i++) { |
| 784 type_argument = arguments.TypeAt(i); | 774 type_argument = arguments.TypeAt(i); |
| 785 type_argument = FinalizeType(cls, type_argument, finalization); | 775 type_argument = FinalizeType(cls, type_argument, finalization); |
| 786 if (type_argument.IsMalformed()) { | 776 if (type_argument.IsMalformed()) { |
| 787 // In production mode, malformed type arguments are mapped to dynamic. | 777 // Malformed type arguments are mapped to dynamic. |
| 788 // In checked mode, a type with malformed type arguments is malformed. | 778 type_argument = Type::DynamicType(); |
| 789 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) { | |
| 790 const Error& error = Error::Handle(type_argument.malformed_error()); | |
| 791 const String& type_name = | |
| 792 String::Handle(parameterized_type.UserVisibleName()); | |
| 793 FinalizeMalformedType(error, cls, parameterized_type, finalization, | |
| 794 "type '%s' has malformed type argument", | |
| 795 type_name.ToCString()); | |
| 796 return parameterized_type.raw(); | |
| 797 } else { | |
| 798 type_argument = Type::DynamicType(); | |
| 799 } | |
| 800 } | 779 } |
| 801 arguments.SetTypeAt(i, type_argument); | 780 arguments.SetTypeAt(i, type_argument); |
| 802 } | 781 } |
| 803 } | 782 } |
| 804 | 783 |
| 805 // The finalized type argument vector needs num_type_arguments types. | 784 // The finalized type argument vector needs num_type_arguments types. |
| 806 const intptr_t num_type_arguments = type_class.NumTypeArguments(); | 785 const intptr_t num_type_arguments = type_class.NumTypeArguments(); |
| 807 // The type class has num_type_parameters type parameters. | 786 // The type class has num_type_parameters type parameters. |
| 808 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 787 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 809 | 788 |
| 810 // Initialize the type argument vector. | 789 // Initialize the type argument vector. |
| 811 // Check the number of parsed type arguments, if any. | 790 // Check the number of parsed type arguments, if any. |
| 812 // Specifying no type arguments indicates a raw type, which is not an error. | 791 // Specifying no type arguments indicates a raw type, which is not an error. |
| 813 // However, type parameter bounds are checked below, even for a raw type. | 792 // However, type parameter bounds are checked below, even for a raw type. |
| 814 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { | 793 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { |
| 815 // Wrong number of type arguments. The type is malformed. | 794 // Wrong number of type arguments. The type is malformed. |
| 816 if (finalization >= kCanonicalizeExpression) { | 795 if (FLAG_error_on_malformed_type) { |
| 817 const Script& script = Script::Handle(cls.script()); | 796 const Script& script = Script::Handle(cls.script()); |
| 818 const String& type_name = | 797 const String& type_class_name = String::Handle(type_class.Name()); |
| 819 String::Handle(parameterized_type.UserVisibleName()); | |
| 820 ReportError(script, parameterized_type.token_pos(), | 798 ReportError(script, parameterized_type.token_pos(), |
| 821 "wrong number of type arguments in type '%s'", | 799 "wrong number of type arguments for class '%s'", |
| 822 type_name.ToCString()); | 800 type_class_name.ToCString()); |
| 823 } | 801 } |
| 824 FinalizeMalformedType( | 802 // Make the type raw and continue without reporting any error. |
| 825 Error::Handle(), // No previous error. | 803 // A static warning should have been reported. |
| 826 cls, parameterized_type, finalization, | 804 arguments = AbstractTypeArguments::null(); |
| 827 "wrong number of type arguments in type '%s'", | 805 parameterized_type.set_arguments(arguments); |
| 828 String::Handle(parameterized_type.UserVisibleName()).ToCString()); | |
| 829 return parameterized_type.raw(); | |
| 830 } | 806 } |
| 831 // The full type argument vector consists of the type arguments of the | 807 // The full type argument vector consists of the type arguments of the |
| 832 // super types of type_class, which may be initialized from the parsed | 808 // super types of type_class, which may be initialized from the parsed |
| 833 // type arguments, followed by the parsed type arguments. | 809 // type arguments, followed by the parsed type arguments. |
| 834 TypeArguments& full_arguments = TypeArguments::Handle(); | 810 TypeArguments& full_arguments = TypeArguments::Handle(); |
| 835 Error& bound_error = Error::Handle(); | 811 Error& bound_error = Error::Handle(); |
| 836 if (num_type_arguments > 0) { | 812 if (num_type_arguments > 0) { |
| 837 // If no type arguments were parsed and if the super types do not prepend | 813 // If no type arguments were parsed and if the super types do not prepend |
| 838 // type arguments to the vector, we can leave the vector as null. | 814 // type arguments to the vector, we can leave the vector as null. |
| 839 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { | 815 if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 if (type_class.IsSignatureClass()) { | 877 if (type_class.IsSignatureClass()) { |
| 902 // The class may be created while parsing a function body, after all | 878 // The class may be created while parsing a function body, after all |
| 903 // pending classes have already been finalized. | 879 // pending classes have already been finalized. |
| 904 FinalizeTypesInClass(type_class); | 880 FinalizeTypesInClass(type_class); |
| 905 } | 881 } |
| 906 | 882 |
| 907 // If a bound error occurred, return a BoundedType with a malformed bound. | 883 // If a bound error occurred, return a BoundedType with a malformed bound. |
| 908 // The malformed bound will be ignored in production mode. | 884 // The malformed bound will be ignored in production mode. |
| 909 if (!bound_error.IsNull()) { | 885 if (!bound_error.IsNull()) { |
| 910 // No compile-time error during finalization. | 886 // No compile-time error during finalization. |
| 911 FinalizationKind bound_finalization = kResolveTypeParameters; | |
| 912 if (FLAG_enable_type_checks || FLAG_error_on_malformed_type) { | |
| 913 bound_finalization = finalization; | |
| 914 } | |
| 915 const String& parameterized_type_name = String::Handle( | 887 const String& parameterized_type_name = String::Handle( |
| 916 parameterized_type.UserVisibleName()); | 888 parameterized_type.UserVisibleName()); |
| 917 const Type& malformed_bound = Type::Handle( | 889 const Type& malformed_bound = Type::Handle( |
| 918 NewFinalizedMalformedType(bound_error, | 890 NewFinalizedMalformedType(bound_error, |
| 919 cls, | 891 cls, |
| 920 parameterized_type.token_pos(), | 892 parameterized_type.token_pos(), |
| 921 bound_finalization, | |
| 922 "type '%s' has an out of bound type argument", | 893 "type '%s' has an out of bound type argument", |
| 923 parameterized_type_name.ToCString())); | 894 parameterized_type_name.ToCString())); |
| 924 return BoundedType::New(parameterized_type, | 895 return BoundedType::New(parameterized_type, |
| 925 malformed_bound, | 896 malformed_bound, |
| 926 TypeParameter::Handle()); | 897 TypeParameter::Handle()); |
| 927 } | 898 } |
| 928 | 899 |
| 929 if (finalization >= kCanonicalize) { | 900 if (finalization >= kCanonicalize) { |
| 930 return parameterized_type.Canonicalize(); | 901 return parameterized_type.Canonicalize(); |
| 931 } else { | 902 } else { |
| 932 return parameterized_type.raw(); | 903 return parameterized_type.raw(); |
| 933 } | 904 } |
| 934 } | 905 } |
| 935 | 906 |
| 936 | 907 |
| 937 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, | 908 void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls, |
| 938 const Function& function) { | 909 const Function& function) { |
| 939 // Resolve result type. | 910 // Resolve result type. |
| 940 AbstractType& type = AbstractType::Handle(function.result_type()); | 911 AbstractType& type = AbstractType::Handle(function.result_type()); |
| 941 // It is not a compile time error if this name does not resolve to a class or | 912 // It is not a compile time error if this name does not resolve to a class or |
| 942 // interface. | 913 // interface. |
| 943 ResolveType(cls, type, kCanonicalize); | 914 ResolveType(cls, type, kCanonicalize); |
| 944 type = FinalizeType(cls, type, kCanonicalize); | 915 type = FinalizeType(cls, type, kCanonicalize); |
| 945 // In production mode, a malformed result type is mapped to dynamic. | 916 // A malformed result type is mapped to dynamic. |
| 946 if (!FLAG_enable_type_checks && type.IsMalformed()) { | 917 ASSERT(!type.IsMalformed()); |
| 947 type = Type::DynamicType(); | |
| 948 } | |
| 949 function.set_result_type(type); | 918 function.set_result_type(type); |
| 950 // Resolve formal parameter types. | 919 // Resolve formal parameter types. |
| 951 const intptr_t num_parameters = function.NumParameters(); | 920 const intptr_t num_parameters = function.NumParameters(); |
| 952 for (intptr_t i = 0; i < num_parameters; i++) { | 921 for (intptr_t i = 0; i < num_parameters; i++) { |
| 953 type = function.ParameterTypeAt(i); | 922 type = function.ParameterTypeAt(i); |
| 954 ResolveType(cls, type, kCanonicalize); | 923 ResolveType(cls, type, kCanonicalize); |
| 955 type = FinalizeType(cls, type, kCanonicalize); | 924 type = FinalizeType(cls, type, kCanonicalize); |
| 956 // In production mode, a malformed parameter type is mapped to dynamic. | 925 // A malformed parameter type is mapped to dynamic. |
| 957 if (!FLAG_enable_type_checks && type.IsMalformed()) { | 926 ASSERT(!type.IsMalformed()); |
| 958 type = Type::DynamicType(); | |
| 959 } | |
| 960 function.SetParameterTypeAt(i, type); | 927 function.SetParameterTypeAt(i, type); |
| 961 } | 928 } |
| 962 } | 929 } |
| 963 | 930 |
| 964 | 931 |
| 965 // Check if an instance field or method of same name exists | 932 // Check if an instance field or method of same name exists |
| 966 // in any super class. | 933 // in any super class. |
| 967 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, | 934 static RawClass* FindSuperOwnerOfInstanceMember(const Class& cls, |
| 968 const String& name) { | 935 const String& name) { |
| 969 Class& super_class = Class::Handle(); | 936 Class& super_class = Class::Handle(); |
| (...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 // are lifted. | 1835 // are lifted. |
| 1869 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); | 1836 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); |
| 1870 | 1837 |
| 1871 // Resolve and check the super type and interfaces of cls. | 1838 // Resolve and check the super type and interfaces of cls. |
| 1872 visited->Add(cls_index); | 1839 visited->Add(cls_index); |
| 1873 AbstractType& interface = AbstractType::Handle(); | 1840 AbstractType& interface = AbstractType::Handle(); |
| 1874 Class& interface_class = Class::Handle(); | 1841 Class& interface_class = Class::Handle(); |
| 1875 | 1842 |
| 1876 // Resolve super type. Failures lead to a longjmp. | 1843 // Resolve super type. Failures lead to a longjmp. |
| 1877 ResolveType(cls, super_type, kCanonicalizeWellFormed); | 1844 ResolveType(cls, super_type, kCanonicalizeWellFormed); |
| 1845 if (super_type.IsMalformed()) { |
| 1846 ReportError(Error::Handle(super_type.malformed_error())); |
| 1847 } |
| 1878 if (super_type.IsDynamicType()) { | 1848 if (super_type.IsDynamicType()) { |
| 1879 const Script& script = Script::Handle(cls.script()); | 1849 const Script& script = Script::Handle(cls.script()); |
| 1880 ReportError(script, cls.token_pos(), | 1850 ReportError(script, cls.token_pos(), |
| 1881 "class '%s' may not extend 'dynamic'", | 1851 "class '%s' may not extend 'dynamic'", |
| 1882 String::Handle(cls.Name()).ToCString()); | 1852 String::Handle(cls.Name()).ToCString()); |
| 1883 } | 1853 } |
| 1884 | 1854 |
| 1885 interface_class = super_type.type_class(); | 1855 interface_class = super_type.type_class(); |
| 1886 // If cls belongs to core lib or to core lib's implementation, restrictions | 1856 // If cls belongs to core lib or to core lib's implementation, restrictions |
| 1887 // about allowed interfaces are lifted. | 1857 // about allowed interfaces are lifted. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 } | 1903 } |
| 1934 } | 1904 } |
| 1935 // Now resolve the super interfaces of the super type. | 1905 // Now resolve the super interfaces of the super type. |
| 1936 ResolveSuperTypeAndInterfaces(interface_class, visited); | 1906 ResolveSuperTypeAndInterfaces(interface_class, visited); |
| 1937 | 1907 |
| 1938 // Resolve interfaces. Failures lead to a longjmp. | 1908 // Resolve interfaces. Failures lead to a longjmp. |
| 1939 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { | 1909 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { |
| 1940 interface ^= super_interfaces.At(i); | 1910 interface ^= super_interfaces.At(i); |
| 1941 ResolveType(cls, interface, kCanonicalizeWellFormed); | 1911 ResolveType(cls, interface, kCanonicalizeWellFormed); |
| 1942 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. | 1912 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. |
| 1913 if (interface.IsMalformed()) { |
| 1914 ReportError(Error::Handle(interface.malformed_error())); |
| 1915 } |
| 1943 if (interface.IsDynamicType()) { | 1916 if (interface.IsDynamicType()) { |
| 1944 const Script& script = Script::Handle(cls.script()); | 1917 const Script& script = Script::Handle(cls.script()); |
| 1945 ReportError(script, cls.token_pos(), | 1918 ReportError(script, cls.token_pos(), |
| 1946 "'dynamic' may not be used as interface"); | 1919 "'dynamic' may not be used as interface"); |
| 1947 } | 1920 } |
| 1948 interface_class = interface.type_class(); | 1921 interface_class = interface.type_class(); |
| 1949 if (interface_class.IsSignatureClass()) { | 1922 if (interface_class.IsSignatureClass()) { |
| 1950 const Script& script = Script::Handle(cls.script()); | 1923 const Script& script = Script::Handle(cls.script()); |
| 1951 ReportError(script, cls.token_pos(), | 1924 ReportError(script, cls.token_pos(), |
| 1952 "'%s' is used where an interface or class name is expected", | 1925 "'%s' is used where an interface or class name is expected", |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2044 for (intptr_t i = 0; i < len; i++) { | 2017 for (intptr_t i = 0; i < len; i++) { |
| 2045 field ^= fields_array.At(i); | 2018 field ^= fields_array.At(i); |
| 2046 OS::Print(" %s\n", field.ToCString()); | 2019 OS::Print(" %s\n", field.ToCString()); |
| 2047 } | 2020 } |
| 2048 } | 2021 } |
| 2049 | 2022 |
| 2050 // Either report an error or mark the type as malformed. | 2023 // Either report an error or mark the type as malformed. |
| 2051 void ClassFinalizer::ReportMalformedType(const Error& prev_error, | 2024 void ClassFinalizer::ReportMalformedType(const Error& prev_error, |
| 2052 const Class& cls, | 2025 const Class& cls, |
| 2053 const Type& type, | 2026 const Type& type, |
| 2054 FinalizationKind finalization, | |
| 2055 const char* format, | 2027 const char* format, |
| 2056 va_list args) { | 2028 va_list args) { |
| 2057 LanguageError& error = LanguageError::Handle(); | 2029 LanguageError& error = LanguageError::Handle(); |
| 2058 if (FLAG_enable_type_checks || | 2030 const Script& script = Script::Handle(cls.script()); |
| 2059 !type.HasResolvedTypeClass() || | 2031 if (prev_error.IsNull()) { |
| 2060 (finalization == kCanonicalizeWellFormed) || | 2032 error ^= Parser::FormatError( |
| 2061 FLAG_error_on_malformed_type) { | 2033 script, type.token_pos(), "Error", format, args); |
| 2062 const Script& script = Script::Handle(cls.script()); | 2034 } else { |
| 2063 if (prev_error.IsNull()) { | 2035 error ^= Parser::FormatErrorWithAppend( |
| 2064 error ^= Parser::FormatError( | 2036 prev_error, script, type.token_pos(), "Error", format, args); |
| 2065 script, type.token_pos(), "Error", format, args); | |
| 2066 } else { | |
| 2067 error ^= Parser::FormatErrorWithAppend( | |
| 2068 prev_error, script, type.token_pos(), "Error", format, args); | |
| 2069 } | |
| 2070 if ((finalization == kCanonicalizeWellFormed) || | |
| 2071 FLAG_error_on_malformed_type) { | |
| 2072 ReportError(error); | |
| 2073 } | |
| 2074 } | 2037 } |
| 2075 // In checked mode, always mark the type as malformed. | 2038 if (FLAG_error_on_malformed_type) { |
| 2076 // In production mode, mark the type as malformed only if its type class is | 2039 ReportError(error); |
| 2077 // not resolved. | 2040 } |
| 2078 // In both mode, make the type raw, since it may not be possible to | 2041 type.set_malformed_error(error); |
| 2042 // Make the type raw, since it may not be possible to |
| 2079 // properly finalize its type arguments. | 2043 // properly finalize its type arguments. |
| 2080 if (FLAG_enable_type_checks || !type.HasResolvedTypeClass()) { | 2044 type.set_type_class(Class::Handle(Object::dynamic_class())); |
| 2081 type.set_malformed_error(error); | |
| 2082 } | |
| 2083 type.set_arguments(Object::null_abstract_type_arguments()); | 2045 type.set_arguments(Object::null_abstract_type_arguments()); |
| 2084 if (!type.IsFinalized()) { | 2046 if (!type.IsFinalized()) { |
| 2085 type.SetIsFinalized(); | 2047 type.SetIsFinalized(); |
| 2086 // Do not canonicalize malformed types, since they may not be resolved. | 2048 // Do not canonicalize malformed types, since they may not be resolved. |
| 2087 } else { | 2049 } else { |
| 2088 // The only case where the malformed type was already finalized is when its | 2050 // The only case where the malformed type was already finalized is when its |
| 2089 // type arguments are not within bounds. In that case, we have a prev_error. | 2051 // type arguments are not within bounds. In that case, we have a prev_error. |
| 2090 ASSERT(!prev_error.IsNull()); | 2052 ASSERT(!prev_error.IsNull()); |
| 2091 } | 2053 } |
| 2092 } | 2054 } |
| 2093 | 2055 |
| 2094 | 2056 |
| 2095 RawType* ClassFinalizer::NewFinalizedMalformedType( | 2057 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error, |
| 2096 const Error& prev_error, | 2058 const Class& cls, |
| 2097 const Class& cls, | 2059 intptr_t type_pos, |
| 2098 intptr_t type_pos, | 2060 const char* format, ...) { |
| 2099 FinalizationKind finalization, | |
| 2100 const char* format, ...) { | |
| 2101 va_list args; | 2061 va_list args; |
| 2102 va_start(args, format); | 2062 va_start(args, format); |
| 2103 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( | 2063 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( |
| 2104 UnresolvedClass::New(LibraryPrefix::Handle(), | 2064 UnresolvedClass::New(LibraryPrefix::Handle(), |
| 2105 Symbols::Empty(), | 2065 Symbols::Empty(), |
| 2106 type_pos)); | 2066 type_pos)); |
| 2107 const Type& type = Type::Handle( | 2067 const Type& type = Type::Handle( |
| 2108 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); | 2068 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); |
| 2109 ReportMalformedType(prev_error, cls, type, finalization, format, args); | 2069 ReportMalformedType(prev_error, cls, type, format, args); |
| 2110 va_end(args); | 2070 va_end(args); |
| 2111 ASSERT(type.IsMalformed()); | 2071 ASSERT(type.IsMalformed()); |
| 2112 ASSERT(type.IsFinalized()); | 2072 ASSERT(type.IsFinalized()); |
| 2113 return type.raw(); | 2073 return type.raw(); |
| 2114 } | 2074 } |
| 2115 | 2075 |
| 2116 | 2076 |
| 2117 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, | 2077 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, |
| 2118 const Class& cls, | 2078 const Class& cls, |
| 2119 const Type& type, | 2079 const Type& type, |
| 2120 FinalizationKind finalization, | |
| 2121 const char* format, ...) { | 2080 const char* format, ...) { |
| 2122 va_list args; | 2081 va_list args; |
| 2123 va_start(args, format); | 2082 va_start(args, format); |
| 2124 ReportMalformedType(prev_error, cls, type, finalization, format, args); | 2083 ReportMalformedType(prev_error, cls, type, format, args); |
| 2125 va_end(args); | 2084 va_end(args); |
| 2126 } | 2085 } |
| 2127 | 2086 |
| 2128 | 2087 |
| 2129 void ClassFinalizer::ReportError(const Error& error) { | 2088 void ClassFinalizer::ReportError(const Error& error) { |
| 2130 Isolate::Current()->long_jump_base()->Jump(1, error); | 2089 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2131 UNREACHABLE(); | 2090 UNREACHABLE(); |
| 2132 } | 2091 } |
| 2133 | 2092 |
| 2134 | 2093 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2207 expected_name ^= String::New("_offset"); | 2166 expected_name ^= String::New("_offset"); |
| 2208 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2167 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2209 field ^= fields_array.At(2); | 2168 field ^= fields_array.At(2); |
| 2210 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2169 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2211 name ^= field.name(); | 2170 name ^= field.name(); |
| 2212 ASSERT(name.Equals("length")); | 2171 ASSERT(name.Equals("length")); |
| 2213 #endif | 2172 #endif |
| 2214 } | 2173 } |
| 2215 | 2174 |
| 2216 } // namespace dart | 2175 } // namespace dart |
| OLD | NEW |