| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 // Verify that the target constructor of the redirection exists. | 458 // Verify that the target constructor of the redirection exists. |
| 459 target = target_class.LookupConstructor(target_name); | 459 target = target_class.LookupConstructor(target_name); |
| 460 if (target.IsNull()) { | 460 if (target.IsNull()) { |
| 461 target = target_class.LookupFactory(target_name); | 461 target = target_class.LookupFactory(target_name); |
| 462 } | 462 } |
| 463 if (target.IsNull()) { | 463 if (target.IsNull()) { |
| 464 const String& user_visible_target_name = | 464 const String& user_visible_target_name = |
| 465 identifier.IsNull() ? target_class_name : target_name; | 465 identifier.IsNull() ? target_class_name : target_name; |
| 466 // Replace the type with a malformed type and compile a throw when called. | 466 // Replace the type with a malformed type and compile a throw when called. |
| 467 type = NewFinalizedMalformedType( | 467 type = NewFinalizedMalformedType( |
| 468 Error::Handle(), // No previous error. |
| 468 cls, | 469 cls, |
| 469 factory.token_pos(), | 470 factory.token_pos(), |
| 471 kTryResolve, // No compile-time error. |
| 470 "class '%s' has no constructor or factory named '%s'", | 472 "class '%s' has no constructor or factory named '%s'", |
| 471 target_class_name.ToCString(), | 473 target_class_name.ToCString(), |
| 472 user_visible_target_name.ToCString()); | 474 user_visible_target_name.ToCString()); |
| 473 factory.SetRedirectionType(type); | 475 factory.SetRedirectionType(type); |
| 474 ASSERT(factory.RedirectionTarget() == Function::null()); | 476 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 475 return; | 477 return; |
| 476 } | 478 } |
| 477 | 479 |
| 478 // Verify that the target is compatible with the redirecting factory. | 480 // Verify that the target is compatible with the redirecting factory. |
| 479 if (!target.HasCompatibleParametersWith(factory)) { | 481 if (!target.HasCompatibleParametersWith(factory)) { |
| 480 type = NewFinalizedMalformedType( | 482 type = NewFinalizedMalformedType( |
| 483 Error::Handle(), // No previous error. |
| 481 cls, | 484 cls, |
| 482 factory.token_pos(), | 485 factory.token_pos(), |
| 486 kTryResolve, // No compile-time error. |
| 483 "constructor '%s' has incompatible parameters with " | 487 "constructor '%s' has incompatible parameters with " |
| 484 "redirecting factory '%s'", | 488 "redirecting factory '%s'", |
| 485 String::Handle(target.name()).ToCString(), | 489 String::Handle(target.name()).ToCString(), |
| 486 String::Handle(factory.name()).ToCString()); | 490 String::Handle(factory.name()).ToCString()); |
| 487 factory.SetRedirectionType(type); | 491 factory.SetRedirectionType(type); |
| 488 ASSERT(factory.RedirectionTarget() == Function::null()); | 492 ASSERT(factory.RedirectionTarget() == Function::null()); |
| 489 return; | 493 return; |
| 490 } | 494 } |
| 491 | 495 |
| 492 // Verify that the target is const if the the redirecting factory is const. | 496 // Verify that the target is const if the the redirecting factory is const. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 } | 534 } |
| 531 factory.SetRedirectionType(target_type); | 535 factory.SetRedirectionType(target_type); |
| 532 factory.SetRedirectionTarget(target_target); | 536 factory.SetRedirectionTarget(target_target); |
| 533 } | 537 } |
| 534 | 538 |
| 535 | 539 |
| 536 void ClassFinalizer::ResolveType(const Class& cls, | 540 void ClassFinalizer::ResolveType(const Class& cls, |
| 537 const AbstractType& type, | 541 const AbstractType& type, |
| 538 FinalizationKind finalization) { | 542 FinalizationKind finalization) { |
| 539 if (type.IsResolved() || type.IsFinalized()) { | 543 if (type.IsResolved() || type.IsFinalized()) { |
| 544 if ((finalization == kCanonicalizeWellFormed) && type.IsMalformed()) { |
| 545 ReportError(Error::Handle(type.malformed_error())); |
| 546 } |
| 540 return; | 547 return; |
| 541 } | 548 } |
| 542 if (FLAG_trace_type_finalization) { | 549 if (FLAG_trace_type_finalization) { |
| 543 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); | 550 OS::Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 544 } | 551 } |
| 545 | 552 |
| 546 // Resolve the type class. | 553 // Resolve the type class. |
| 547 if (!type.HasResolvedTypeClass()) { | 554 if (!type.HasResolvedTypeClass()) { |
| 548 // Type parameters are always resolved in the parser in the correct | 555 // Type parameters are always resolved in the parser in the correct |
| 549 // non-static scope or factory scope. That resolution scope is unknown here. | 556 // non-static scope or factory scope. That resolution scope is unknown here. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 } | 676 } |
| 670 FinalizeTypeArguments(super_class, arguments, finalization); | 677 FinalizeTypeArguments(super_class, arguments, finalization); |
| 671 } | 678 } |
| 672 } | 679 } |
| 673 | 680 |
| 674 | 681 |
| 675 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, | 682 RawAbstractType* ClassFinalizer::FinalizeType(const Class& cls, |
| 676 const AbstractType& type, | 683 const AbstractType& type, |
| 677 FinalizationKind finalization) { | 684 FinalizationKind finalization) { |
| 678 if (type.IsFinalized()) { | 685 if (type.IsFinalized()) { |
| 679 // Ensure type is canonical if canonicalization is requested. | 686 // Ensure type is canonical if canonicalization is requested, unless type is |
| 687 // malformed. |
| 680 if (finalization >= kCanonicalize) { | 688 if (finalization >= kCanonicalize) { |
| 681 return type.Canonicalize(); | 689 if (type.IsMalformed()) { |
| 690 if (finalization == kCanonicalizeWellFormed) { |
| 691 ReportError(Error::Handle(type.malformed_error())); |
| 692 } |
| 693 } else { |
| 694 return type.Canonicalize(); |
| 695 } |
| 682 } | 696 } |
| 683 return type.raw(); | 697 return type.raw(); |
| 684 } | 698 } |
| 685 ASSERT(type.IsResolved()); | 699 ASSERT(type.IsResolved()); |
| 686 ASSERT(finalization >= kFinalize); | 700 ASSERT(finalization >= kFinalize); |
| 687 | 701 |
| 688 if (FLAG_trace_type_finalization) { | 702 if (FLAG_trace_type_finalization) { |
| 689 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); | 703 OS::Print("Finalize type '%s'\n", String::Handle(type.Name()).ToCString()); |
| 690 } | 704 } |
| 691 | 705 |
| (...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 type.set_is_finalized_instantiated(); | 1542 type.set_is_finalized_instantiated(); |
| 1529 // Do not canonicalize malformed types, since they may not be resolved. | 1543 // Do not canonicalize malformed types, since they may not be resolved. |
| 1530 } else { | 1544 } else { |
| 1531 // The only case where the malformed type was already finalized is when its | 1545 // The only case where the malformed type was already finalized is when its |
| 1532 // type arguments are not within bounds. In that case, we have a prev_error. | 1546 // type arguments are not within bounds. In that case, we have a prev_error. |
| 1533 ASSERT(!prev_error.IsNull()); | 1547 ASSERT(!prev_error.IsNull()); |
| 1534 } | 1548 } |
| 1535 } | 1549 } |
| 1536 | 1550 |
| 1537 | 1551 |
| 1538 RawType* ClassFinalizer::NewFinalizedMalformedType(const Class& cls, | 1552 RawType* ClassFinalizer::NewFinalizedMalformedType( |
| 1539 intptr_t type_pos, | 1553 const Error& prev_error, |
| 1540 const char* format, ...) { | 1554 const Class& cls, |
| 1555 intptr_t type_pos, |
| 1556 FinalizationKind finalization, |
| 1557 const char* format, ...) { |
| 1541 va_list args; | 1558 va_list args; |
| 1542 va_start(args, format); | 1559 va_start(args, format); |
| 1543 const String& no_name = String::Handle(Symbols::Empty()); | 1560 const String& no_name = String::Handle(Symbols::Empty()); |
| 1544 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( | 1561 const UnresolvedClass& unresolved_class = UnresolvedClass::Handle( |
| 1545 UnresolvedClass::New(LibraryPrefix::Handle(), no_name, type_pos)); | 1562 UnresolvedClass::New(LibraryPrefix::Handle(), no_name, type_pos)); |
| 1546 const Type& type = Type::Handle( | 1563 const Type& type = Type::Handle( |
| 1547 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); | 1564 Type::New(unresolved_class, TypeArguments::Handle(), type_pos)); |
| 1548 ReportMalformedType(Error::Handle(), cls, type, kTryResolve, format, args); | 1565 ReportMalformedType(prev_error, cls, type, finalization, format, args); |
| 1549 va_end(args); | 1566 va_end(args); |
| 1550 ASSERT(type.IsMalformed()); | 1567 ASSERT(type.IsMalformed()); |
| 1551 return type.raw(); | 1568 return type.raw(); |
| 1552 } | 1569 } |
| 1553 | 1570 |
| 1554 | 1571 |
| 1555 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, | 1572 void ClassFinalizer::FinalizeMalformedType(const Error& prev_error, |
| 1556 const Class& cls, | 1573 const Class& cls, |
| 1557 const Type& type, | 1574 const Type& type, |
| 1558 FinalizationKind finalization, | 1575 FinalizationKind finalization, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1585 void ClassFinalizer::ReportError(const char* format, ...) { | 1602 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1586 va_list args; | 1603 va_list args; |
| 1587 va_start(args, format); | 1604 va_start(args, format); |
| 1588 const Error& error = Error::Handle( | 1605 const Error& error = Error::Handle( |
| 1589 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1606 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1590 va_end(args); | 1607 va_end(args); |
| 1591 ReportError(error); | 1608 ReportError(error); |
| 1592 } | 1609 } |
| 1593 | 1610 |
| 1594 } // namespace dart | 1611 } // namespace dart |
| OLD | NEW |