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 |