| 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 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 500 // i.e. cls_args = [String, double], offset = 2, length = 2. | 500 // i.e. cls_args = [String, double], offset = 2, length = 2. |
| 501 // Output: arguments = [int, double, String, double] | 501 // Output: arguments = [int, double, String, double] |
| 502 void ClassFinalizer::FinalizeTypeArguments( | 502 void ClassFinalizer::FinalizeTypeArguments( |
| 503 const Class& cls, | 503 const Class& cls, |
| 504 const AbstractTypeArguments& arguments, | 504 const AbstractTypeArguments& arguments, |
| 505 FinalizationKind finalization, | 505 FinalizationKind finalization, |
| 506 Error* bound_error) { | 506 Error* bound_error) { |
| 507 ASSERT(arguments.Length() >= cls.NumTypeArguments()); | 507 ASSERT(arguments.Length() >= cls.NumTypeArguments()); |
| 508 if (!cls.is_finalized()) { | 508 if (!cls.is_finalized()) { |
| 509 FinalizeTypeParameters(cls); | 509 FinalizeTypeParameters(cls); |
| 510 ResolveUpperBounds(cls); |
| 510 } | 511 } |
| 511 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 512 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 512 if (!super_type.IsNull()) { | 513 if (!super_type.IsNull()) { |
| 513 const Class& super_class = Class::Handle(super_type.type_class()); | 514 const Class& super_class = Class::Handle(super_type.type_class()); |
| 514 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); | 515 AbstractTypeArguments& super_type_args = AbstractTypeArguments::Handle(); |
| 515 if (super_type.IsBeingFinalized()) { | 516 if (super_type.IsBeingFinalized()) { |
| 516 // This type references itself via its type arguments. This is legal, but | 517 // This type references itself via its type arguments. This is legal, but |
| 517 // we must avoid endless recursion. We therefore map the innermost | 518 // we must avoid endless recursion. We therefore map the innermost |
| 518 // super type to dynamic. | 519 // super type to dynamic. |
| 519 // Note that a direct self-reference via the super class chain is illegal | 520 // Note that a direct self-reference via the super class chain is illegal |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 // Check the type argument vector 'arguments' against the corresponding bounds | 568 // Check the type argument vector 'arguments' against the corresponding bounds |
| 568 // of the type parameters of class 'cls' and, recursively, of its superclasses. | 569 // of the type parameters of class 'cls' and, recursively, of its superclasses. |
| 569 // Replace a type argument that cannot be checked at compile time by a | 570 // Replace a type argument that cannot be checked at compile time by a |
| 570 // BoundedType, thereby postponing the bound check to run time. | 571 // BoundedType, thereby postponing the bound check to run time. |
| 571 // Return a bound error if a type argument is not within bound at compile time. | 572 // Return a bound error if a type argument is not within bound at compile time. |
| 572 void ClassFinalizer::CheckTypeArgumentBounds( | 573 void ClassFinalizer::CheckTypeArgumentBounds( |
| 573 const Class& cls, | 574 const Class& cls, |
| 574 const AbstractTypeArguments& arguments, | 575 const AbstractTypeArguments& arguments, |
| 575 Error* bound_error) { | 576 Error* bound_error) { |
| 576 if (!cls.is_finalized()) { | 577 if (!cls.is_finalized()) { |
| 577 ResolveAndFinalizeUpperBounds(cls); | 578 FinalizeUpperBounds(cls); |
| 578 } | 579 } |
| 579 // Note that when finalizing a type, we need to verify the bounds in both | 580 // Note that when finalizing a type, we need to verify the bounds in both |
| 580 // production mode and checked mode, because the finalized type may be written | 581 // production mode and checked mode, because the finalized type may be written |
| 581 // to a snapshot. It would be wrong to ignore bounds when generating the | 582 // to a snapshot. It would be wrong to ignore bounds when generating the |
| 582 // snapshot in production mode and then use the unchecked type in checked mode | 583 // snapshot in production mode and then use the unchecked type in checked mode |
| 583 // after reading it from the snapshot. | 584 // after reading it from the snapshot. |
| 584 // However, we do not immediately report a bound error, which would be wrong | 585 // However, we do not immediately report a bound error, which would be wrong |
| 585 // in production mode, but simply postpone the bound checking to runtime. | 586 // in production mode, but simply postpone the bound checking to runtime. |
| 586 const intptr_t num_type_params = cls.NumTypeParameters(); | 587 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 587 const intptr_t offset = cls.NumTypeArguments() - num_type_params; | 588 const intptr_t offset = cls.NumTypeArguments() - num_type_params; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 600 } | 601 } |
| 601 cls_type_param = cls_type_params.TypeAt(i); | 602 cls_type_param = cls_type_params.TypeAt(i); |
| 602 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); | 603 const TypeParameter& type_param = TypeParameter::Cast(cls_type_param); |
| 603 ASSERT(type_param.IsFinalized()); | 604 ASSERT(type_param.IsFinalized()); |
| 604 declared_bound = type_param.bound(); | 605 declared_bound = type_param.bound(); |
| 605 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { | 606 if (!declared_bound.IsObjectType() && !declared_bound.IsDynamicType()) { |
| 606 Error& malformed_error = Error::Handle(); | 607 Error& malformed_error = Error::Handle(); |
| 607 // Note that the bound may be malformed, in which case the bound check | 608 // Note that the bound may be malformed, in which case the bound check |
| 608 // will return an error and the bound check will be postponed to run time. | 609 // will return an error and the bound check will be postponed to run time. |
| 609 // Note also that the bound may still be unfinalized. | 610 // Note also that the bound may still be unfinalized. |
| 610 if (!declared_bound.IsFinalized()) { | |
| 611 ASSERT(declared_bound.IsBeingFinalized()); | |
| 612 // The bound refers to type parameters, creating a cycle; postpone | |
| 613 // bound check to run time, when the bound will be finalized. | |
| 614 // TODO(regis): Do we need to instantiate an uninstantiated bound here? | |
| 615 type_arg = BoundedType::New(type_arg, declared_bound, type_param); | |
| 616 arguments.SetTypeAt(offset + i, type_arg); | |
| 617 continue; | |
| 618 } | |
| 619 if (declared_bound.IsInstantiated()) { | 611 if (declared_bound.IsInstantiated()) { |
| 620 instantiated_bound = declared_bound.raw(); | 612 instantiated_bound = declared_bound.raw(); |
| 621 } else { | 613 } else { |
| 622 instantiated_bound = | 614 instantiated_bound = |
| 623 declared_bound.InstantiateFrom(arguments, &malformed_error); | 615 declared_bound.InstantiateFrom(arguments, &malformed_error); |
| 624 } | 616 } |
| 617 if (!instantiated_bound.IsFinalized()) { |
| 618 // The bound refers to type parameters, creating a cycle; postpone |
| 619 // bound check to run time, when the bound will be finalized. |
| 620 // The bound may not necessarily be 'IsBeingFinalized' yet, as is the |
| 621 // case with a pair of type parameters of the same class referring to |
| 622 // each other via their bounds. |
| 623 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
| 624 arguments.SetTypeAt(offset + i, type_arg); |
| 625 continue; |
| 626 } |
| 625 // TODO(regis): We could simplify this code if we could differentiate | 627 // TODO(regis): We could simplify this code if we could differentiate |
| 626 // between a failed bound check and a bound check that is undecidable at | 628 // between a failed bound check and a bound check that is undecidable at |
| 627 // compile time. | 629 // compile time. |
| 628 // Shortcut the special case where we check a type parameter against its | 630 // Shortcut the special case where we check a type parameter against its |
| 629 // declared upper bound. | 631 // declared upper bound. |
| 632 bool below_bound = true; |
| 630 if (malformed_error.IsNull() && | 633 if (malformed_error.IsNull() && |
| 631 (!type_arg.Equals(type_param) || | 634 (!type_arg.Equals(type_param) || |
| 632 !instantiated_bound.Equals(declared_bound))) { | 635 !instantiated_bound.Equals(declared_bound))) { |
| 633 type_param.CheckBound(type_arg, instantiated_bound, &malformed_error); | 636 // Pass NULL to prevent expensive and unnecessary error formatting in |
| 637 // the case the bound check is postponed to run time. |
| 638 below_bound = type_param.CheckBound(type_arg, instantiated_bound, NULL); |
| 634 } | 639 } |
| 635 if (!malformed_error.IsNull()) { | 640 if (!malformed_error.IsNull() || !below_bound) { |
| 636 if (!type_arg.IsInstantiated() || | 641 if (!type_arg.IsInstantiated() || |
| 637 !instantiated_bound.IsInstantiated()) { | 642 !instantiated_bound.IsInstantiated()) { |
| 638 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); | 643 type_arg = BoundedType::New(type_arg, instantiated_bound, type_param); |
| 639 arguments.SetTypeAt(offset + i, type_arg); | 644 arguments.SetTypeAt(offset + i, type_arg); |
| 640 } else if (bound_error->IsNull()) { | 645 } else if (bound_error->IsNull()) { |
| 646 if (malformed_error.IsNull()) { |
| 647 // Call CheckBound again to format error message. |
| 648 type_param.CheckBound(type_arg, |
| 649 instantiated_bound, |
| 650 &malformed_error); |
| 651 } |
| 652 ASSERT(!malformed_error.IsNull()); |
| 641 *bound_error = malformed_error.raw(); | 653 *bound_error = malformed_error.raw(); |
| 642 } | 654 } |
| 643 } | 655 } |
| 644 } | 656 } |
| 645 } | 657 } |
| 646 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 658 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 647 if (!super_type.IsNull()) { | 659 if (!super_type.IsNull()) { |
| 648 const Class& super_class = Class::Handle(super_type.type_class()); | 660 const Class& super_class = Class::Handle(super_type.type_class()); |
| 649 CheckTypeArgumentBounds(super_class, arguments, bound_error); | 661 CheckTypeArgumentBounds(super_class, arguments, bound_error); |
| 650 } | 662 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 parameterized_type.set_is_being_finalized(); | 722 parameterized_type.set_is_being_finalized(); |
| 711 | 723 |
| 712 // The type class does not need to be finalized in order to finalize the type, | 724 // The type class does not need to be finalized in order to finalize the type, |
| 713 // however, it must at least be resolved (this was done as part of resolving | 725 // however, it must at least be resolved (this was done as part of resolving |
| 714 // the type itself, a precondition to calling FinalizeType). | 726 // the type itself, a precondition to calling FinalizeType). |
| 715 // Also, the interfaces of the type class must be resolved and the type | 727 // Also, the interfaces of the type class must be resolved and the type |
| 716 // parameters of the type class must be finalized. | 728 // parameters of the type class must be finalized. |
| 717 Class& type_class = Class::Handle(parameterized_type.type_class()); | 729 Class& type_class = Class::Handle(parameterized_type.type_class()); |
| 718 if (!type_class.is_finalized()) { | 730 if (!type_class.is_finalized()) { |
| 719 FinalizeTypeParameters(type_class); | 731 FinalizeTypeParameters(type_class); |
| 732 ResolveUpperBounds(type_class); |
| 720 } | 733 } |
| 721 | 734 |
| 722 // Finalize the current type arguments of the type, which are still the | 735 // Finalize the current type arguments of the type, which are still the |
| 723 // parsed type arguments. | 736 // parsed type arguments. |
| 724 AbstractTypeArguments& arguments = | 737 AbstractTypeArguments& arguments = |
| 725 AbstractTypeArguments::Handle(parameterized_type.arguments()); | 738 AbstractTypeArguments::Handle(parameterized_type.arguments()); |
| 726 if (!arguments.IsNull()) { | 739 if (!arguments.IsNull()) { |
| 727 intptr_t num_arguments = arguments.Length(); | 740 intptr_t num_arguments = arguments.Length(); |
| 728 AbstractType& type_argument = AbstractType::Handle(); | 741 AbstractType& type_argument = AbstractType::Handle(); |
| 729 for (intptr_t i = 0; i < num_arguments; i++) { | 742 for (intptr_t i = 0; i < num_arguments; i++) { |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 !function.is_static() && | 984 !function.is_static() && |
| 972 !function.IsMethodExtractor()) { | 985 !function.IsMethodExtractor()) { |
| 973 return super_class.raw(); | 986 return super_class.raw(); |
| 974 } | 987 } |
| 975 super_class = super_class.SuperClass(); | 988 super_class = super_class.SuperClass(); |
| 976 } | 989 } |
| 977 return Class::null(); | 990 return Class::null(); |
| 978 } | 991 } |
| 979 | 992 |
| 980 | 993 |
| 981 // Resolve and finalize the upper bounds of the type parameters of class cls. | 994 // Resolve the upper bounds of the type parameters of class cls. |
| 982 void ClassFinalizer::ResolveAndFinalizeUpperBounds(const Class& cls) { | 995 void ClassFinalizer::ResolveUpperBounds(const Class& cls) { |
| 983 const intptr_t num_type_params = cls.NumTypeParameters(); | 996 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 984 TypeParameter& type_param = TypeParameter::Handle(); | 997 TypeParameter& type_param = TypeParameter::Handle(); |
| 985 AbstractType& bound = AbstractType::Handle(); | 998 AbstractType& bound = AbstractType::Handle(); |
| 986 const AbstractTypeArguments& type_params = | 999 const AbstractTypeArguments& type_params = |
| 987 AbstractTypeArguments::Handle(cls.type_parameters()); | 1000 AbstractTypeArguments::Handle(cls.type_parameters()); |
| 988 ASSERT((type_params.IsNull() && (num_type_params == 0)) || | 1001 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
| 989 (type_params.Length() == num_type_params)); | 1002 (type_params.Length() == num_type_params)); |
| 1003 // In a first pass, resolve all bounds. This guarantees that finalization |
| 1004 // of mutually referencing bounds will not encounter an unresolved bound. |
| 1005 for (intptr_t i = 0; i < num_type_params; i++) { |
| 1006 type_param ^= type_params.TypeAt(i); |
| 1007 bound = type_param.bound(); |
| 1008 ResolveType(cls, bound, kCanonicalize); |
| 1009 } |
| 1010 } |
| 1011 |
| 1012 |
| 1013 // Finalize the upper bounds of the type parameters of class cls. |
| 1014 void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { |
| 1015 const intptr_t num_type_params = cls.NumTypeParameters(); |
| 1016 TypeParameter& type_param = TypeParameter::Handle(); |
| 1017 AbstractType& bound = AbstractType::Handle(); |
| 1018 const AbstractTypeArguments& type_params = |
| 1019 AbstractTypeArguments::Handle(cls.type_parameters()); |
| 1020 ASSERT((type_params.IsNull() && (num_type_params == 0)) || |
| 1021 (type_params.Length() == num_type_params)); |
| 990 for (intptr_t i = 0; i < num_type_params; i++) { | 1022 for (intptr_t i = 0; i < num_type_params; i++) { |
| 991 type_param ^= type_params.TypeAt(i); | 1023 type_param ^= type_params.TypeAt(i); |
| 992 bound = type_param.bound(); | 1024 bound = type_param.bound(); |
| 993 if (bound.IsFinalized() || bound.IsBeingFinalized()) { | 1025 if (bound.IsFinalized() || bound.IsBeingFinalized()) { |
| 994 // A bound involved in F-bounded quantification may form a cycle. | 1026 // A bound involved in F-bounded quantification may form a cycle. |
| 995 continue; | 1027 continue; |
| 996 } | 1028 } |
| 997 ResolveType(cls, bound, kCanonicalize); | |
| 998 bound = FinalizeType(cls, bound, kCanonicalize); | 1029 bound = FinalizeType(cls, bound, kCanonicalize); |
| 999 type_param.set_bound(bound); | 1030 type_param.set_bound(bound); |
| 1000 } | 1031 } |
| 1001 } | 1032 } |
| 1002 | 1033 |
| 1003 | 1034 |
| 1004 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { | 1035 void ClassFinalizer::ResolveAndFinalizeMemberTypes(const Class& cls) { |
| 1005 // Note that getters and setters are explicitly listed as such in the list of | 1036 // Note that getters and setters are explicitly listed as such in the list of |
| 1006 // functions of a class, so we do not need to consider fields as implicitly | 1037 // functions of a class, so we do not need to consider fields as implicitly |
| 1007 // generating getters and setters. | 1038 // generating getters and setters. |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 FinalizeClass(super_class); | 1393 FinalizeClass(super_class); |
| 1363 } | 1394 } |
| 1364 if (cls.mixin() != Type::null()) { | 1395 if (cls.mixin() != Type::null()) { |
| 1365 // Copy instance methods and fields from the mixin class. | 1396 // Copy instance methods and fields from the mixin class. |
| 1366 // This has to happen before the check whether the methods of | 1397 // This has to happen before the check whether the methods of |
| 1367 // the class conflict with inherited methods. | 1398 // the class conflict with inherited methods. |
| 1368 ApplyMixin(cls); | 1399 ApplyMixin(cls); |
| 1369 } | 1400 } |
| 1370 // Finalize type parameters before finalizing the super type. | 1401 // Finalize type parameters before finalizing the super type. |
| 1371 FinalizeTypeParameters(cls); | 1402 FinalizeTypeParameters(cls); |
| 1403 ResolveUpperBounds(cls); |
| 1372 // Finalize super type. | 1404 // Finalize super type. |
| 1373 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1405 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 1374 if (!super_type.IsNull()) { | 1406 if (!super_type.IsNull()) { |
| 1375 // In case of a bound error in the super type in production mode, the | 1407 // In case of a bound error in the super type in production mode, the |
| 1376 // finalized super type will be a BoundedType with a malformed bound. | 1408 // finalized super type will be a BoundedType with a malformed bound. |
| 1377 // It should not be a problem if the class is written to a snapshot and | 1409 // It should not be a problem if the class is written to a snapshot and |
| 1378 // later executed in checked mode. Note that the finalized type argument | 1410 // later executed in checked mode. Note that the finalized type argument |
| 1379 // vector of any type of the base class will contain a BoundedType for the | 1411 // vector of any type of the base class will contain a BoundedType for the |
| 1380 // out of bound type argument. | 1412 // out of bound type argument. |
| 1381 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); | 1413 super_type = FinalizeType(cls, super_type, kCanonicalizeWellFormed); |
| 1382 cls.set_super_type(super_type); | 1414 cls.set_super_type(super_type); |
| 1383 } | 1415 } |
| 1384 if (cls.IsSignatureClass()) { | 1416 if (cls.IsSignatureClass()) { |
| 1385 // Check for illegal self references. | 1417 // Check for illegal self references. |
| 1386 GrowableArray<intptr_t> visited_aliases; | 1418 GrowableArray<intptr_t> visited_aliases; |
| 1387 if (!IsAliasCycleFree(cls, &visited_aliases)) { | 1419 if (!IsAliasCycleFree(cls, &visited_aliases)) { |
| 1388 const String& name = String::Handle(cls.Name()); | 1420 const String& name = String::Handle(cls.Name()); |
| 1389 const Script& script = Script::Handle(cls.script()); | 1421 const Script& script = Script::Handle(cls.script()); |
| 1390 ReportError(script, cls.token_pos(), | 1422 ReportError(script, cls.token_pos(), |
| 1391 "typedef '%s' illegally refers to itself", | 1423 "typedef '%s' illegally refers to itself", |
| 1392 name.ToCString()); | 1424 name.ToCString()); |
| 1393 } | 1425 } |
| 1394 cls.Finalize(); | 1426 cls.Finalize(); |
| 1395 // Signature classes extend Object. No need to add this class to the direct | 1427 // Signature classes extend Object. No need to add this class to the direct |
| 1396 // subclasses of Object. | 1428 // subclasses of Object. |
| 1397 ASSERT(super_type.IsNull() || super_type.IsObjectType()); | 1429 ASSERT(super_type.IsNull() || super_type.IsObjectType()); |
| 1398 | 1430 |
| 1399 // The type parameters of signature classes may have bounds. | 1431 // The type parameters of signature classes may have bounds. |
| 1400 ResolveAndFinalizeUpperBounds(cls); | 1432 FinalizeUpperBounds(cls); |
| 1401 | 1433 |
| 1402 // Resolve and finalize the result and parameter types of the signature | 1434 // Resolve and finalize the result and parameter types of the signature |
| 1403 // function of this signature class. | 1435 // function of this signature class. |
| 1404 const Function& sig_function = Function::Handle(cls.signature_function()); | 1436 const Function& sig_function = Function::Handle(cls.signature_function()); |
| 1405 ResolveAndFinalizeSignature(cls, sig_function); | 1437 ResolveAndFinalizeSignature(cls, sig_function); |
| 1406 | 1438 |
| 1407 // Resolve and finalize the signature type of this signature class. | 1439 // Resolve and finalize the signature type of this signature class. |
| 1408 const Type& sig_type = Type::Handle(cls.SignatureType()); | 1440 const Type& sig_type = Type::Handle(cls.SignatureType()); |
| 1409 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); | 1441 FinalizeType(cls, sig_type, kCanonicalizeWellFormed); |
| 1410 return; | 1442 return; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1441 String::Handle(interface_type.Name()).ToCString(), | 1473 String::Handle(interface_type.Name()).ToCString(), |
| 1442 String::Handle(cls.Name()).ToCString()); | 1474 String::Handle(cls.Name()).ToCString()); |
| 1443 } | 1475 } |
| 1444 } | 1476 } |
| 1445 } | 1477 } |
| 1446 // Mark as finalized before resolving type parameter upper bounds and member | 1478 // Mark as finalized before resolving type parameter upper bounds and member |
| 1447 // types in order to break cycles. | 1479 // types in order to break cycles. |
| 1448 cls.Finalize(); | 1480 cls.Finalize(); |
| 1449 // Finalize bounds even if running in production mode, so that a snapshot | 1481 // Finalize bounds even if running in production mode, so that a snapshot |
| 1450 // contains them. | 1482 // contains them. |
| 1451 ResolveAndFinalizeUpperBounds(cls); | 1483 FinalizeUpperBounds(cls); |
| 1452 ResolveAndFinalizeMemberTypes(cls); | 1484 ResolveAndFinalizeMemberTypes(cls); |
| 1453 // Run additional checks after all types are finalized. | 1485 // Run additional checks after all types are finalized. |
| 1454 if (cls.is_const()) { | 1486 if (cls.is_const()) { |
| 1455 CheckForLegalConstClass(cls); | 1487 CheckForLegalConstClass(cls); |
| 1456 } | 1488 } |
| 1457 // Add this class to the direct subclasses of the superclass, unless the | 1489 // Add this class to the direct subclasses of the superclass, unless the |
| 1458 // superclass is Object. | 1490 // superclass is Object. |
| 1459 if (!super_type.IsNull() && !super_type.IsObjectType()) { | 1491 if (!super_type.IsNull() && !super_type.IsObjectType()) { |
| 1460 ASSERT(!super_class.IsNull()); | 1492 ASSERT(!super_class.IsNull()); |
| 1461 super_class.AddDirectSubclass(cls); | 1493 super_class.AddDirectSubclass(cls); |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 void ClassFinalizer::ReportError(const char* format, ...) { | 1967 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1936 va_list args; | 1968 va_list args; |
| 1937 va_start(args, format); | 1969 va_start(args, format); |
| 1938 const Error& error = Error::Handle( | 1970 const Error& error = Error::Handle( |
| 1939 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1971 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1940 va_end(args); | 1972 va_end(args); |
| 1941 ReportError(error); | 1973 ReportError(error); |
| 1942 } | 1974 } |
| 1943 | 1975 |
| 1944 } // namespace dart | 1976 } // namespace dart |
| OLD | NEW |