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 |