Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/ast.h" | 5 #include "vm/ast.h" |
| 6 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
| 7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 | 554 |
| 555 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { | 555 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { |
| 556 return new StoreIndexedNode(token_pos(), array(), index_expr(), | 556 return new StoreIndexedNode(token_pos(), array(), index_expr(), |
| 557 rhs, super_class()); | 557 rhs, super_class()); |
| 558 } | 558 } |
| 559 | 559 |
| 560 | 560 |
| 561 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { | 561 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { |
| 562 if (is_super_getter()) { | 562 if (is_super_getter()) { |
| 563 ASSERT(receiver() != NULL); | 563 ASSERT(receiver() != NULL); |
| 564 // If the static setter is not found in the superclass, noSuchMethod will be | 564 const String& setter_name = |
| 565 // called at runtime. | 565 String::ZoneHandle(Field::SetterSymbol(field_name_)); |
| 566 Function& setter = Function::ZoneHandle( | |
| 567 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); | |
| 568 if (setter.IsNull() || setter.is_abstract()) { | |
| 569 // No instance setter found in super class chain, | |
| 570 // noSuchMethod will be called at runtime. | |
| 571 return new StaticSetterNode(token_pos(), | |
| 572 receiver(), | |
| 573 cls(), | |
| 574 field_name_, | |
| 575 rhs); | |
| 576 } | |
| 566 return new StaticSetterNode(token_pos(), | 577 return new StaticSetterNode(token_pos(), |
| 567 receiver(), | 578 receiver(), |
| 568 cls(), | 579 field_name_, |
| 569 field_name(), | 580 setter, |
| 570 rhs); | 581 rhs); |
| 571 } | 582 } |
| 572 | 583 |
| 584 if (owner().IsLibraryPrefix()) { | |
| 585 const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_); | |
| 586 // The parser has already dealt with the pathological case where a | |
| 587 // library imports itself. See Parser::ResolveIdentInPrefixScope() | |
| 588 ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart); | |
| 589 | |
| 590 // If the prefix is not yet loaded, the getter doesn't exist. Return a | |
| 591 // setter that will throw a NSME at runtime. | |
| 592 if (!prefix.is_loaded()) { | |
| 593 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | |
| 594 } | |
| 595 | |
| 596 Object& obj = Object::Handle(prefix.LookupObject(field_name_)); | |
| 597 if (obj.IsField()) { | |
| 598 const Field& field = Field::ZoneHandle(Field::Cast(obj).raw()); | |
| 599 if (!field.is_final()) { | |
| 600 if (Isolate::Current()->TypeChecksEnabled()) { | |
| 601 rhs = new AssignableNode(field.token_pos(), | |
| 602 rhs, | |
| 603 AbstractType::ZoneHandle(field.type()), | |
| 604 field_name_); | |
| 605 } | |
| 606 return new StoreStaticFieldNode(token_pos(), field, rhs); | |
|
regis
2015/04/21 17:30:30
Indent lines 600-606.
hausner
2015/04/21 17:40:11
Done.
| |
| 607 } | |
| 608 } | |
| 609 | |
| 610 // No field found in prefix. Look for a setter function. | |
| 611 const String& setter_name = String::Handle(Field::SetterName(field_name_)); | |
| 612 obj = prefix.LookupObject(setter_name); | |
| 613 if (obj.IsFunction()) { | |
| 614 const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw()); | |
| 615 ASSERT(setter.is_static() && setter.IsSetterFunction()); | |
| 616 return new StaticSetterNode( | |
| 617 token_pos(), NULL, field_name_, setter, rhs); | |
| 618 } | |
| 619 | |
| 620 // No writeable field and no setter found in the prefix. Return a | |
| 621 // non-existing setter that will throw an NSM error. | |
| 622 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | |
| 623 } | |
| 624 | |
| 625 if (owner().IsLibrary()) { | |
| 626 const Library& library = Library::Cast(owner()); | |
| 627 Object& obj = Object::Handle(library.ResolveName(field_name_)); | |
| 628 if (obj.IsField()) { | |
| 629 const Field& field = Field::ZoneHandle(Field::Cast(obj).raw()); | |
| 630 if (!field.is_final()) { | |
| 631 if (Isolate::Current()->TypeChecksEnabled()) { | |
| 632 rhs = new AssignableNode(field.token_pos(), | |
| 633 rhs, | |
| 634 AbstractType::ZoneHandle(field.type()), | |
| 635 field_name_); | |
| 636 } | |
| 637 return new StoreStaticFieldNode(token_pos(), field, rhs); | |
| 638 } | |
| 639 } | |
| 640 | |
| 641 // No field found in library. Look for a setter function. | |
| 642 const String& setter_name = String::Handle(Field::SetterName(field_name_)); | |
| 643 obj = library.ResolveName(setter_name); | |
| 644 if (obj.IsFunction()) { | |
| 645 const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw()); | |
| 646 ASSERT(setter.is_static() && setter.IsSetterFunction()); | |
| 647 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); | |
| 648 } | |
| 649 | |
| 650 // No writeable field and no setter found in the library. Return a | |
| 651 // non-existing setter that will throw an NSM error. | |
| 652 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | |
| 653 } | |
| 654 | |
| 573 const Function& setter = | 655 const Function& setter = |
| 574 Function::Handle(cls().LookupSetterFunction(field_name())); | 656 Function::ZoneHandle(cls().LookupSetterFunction(field_name_)); |
| 575 if (!setter.IsNull() && setter.IsStaticFunction()) { | 657 if (!setter.IsNull() && setter.IsStaticFunction()) { |
| 576 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 658 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); |
| 577 } | 659 } |
| 578 // Could not find a static setter. Look for a field. | 660 // Could not find a static setter. Look for a field. |
| 579 // Access to a lazily initialized static field that has not yet been | 661 // Access to a lazily initialized static field that has not yet been |
| 580 // initialized is compiled to a static implicit getter. | 662 // initialized is compiled to a static implicit getter. |
| 581 // A setter may not exist for such a field. | 663 // A setter may not exist for such a field. |
| 582 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name())); | 664 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name_)); |
| 583 if (!field.IsNull()) { | 665 if (!field.IsNull()) { |
| 584 if (field.is_final()) { | 666 if (field.is_final()) { |
| 585 // Attempting to assign to a final variable will cause a NoSuchMethodError | 667 // Attempting to assign to a final variable will cause a NoSuchMethodError |
| 586 // to be thrown. Change static getter to non-existent static setter in | 668 // to be thrown. Change static getter to non-existent static setter in |
| 587 // order to trigger the throw at runtime. | 669 // order to trigger the throw at runtime. |
| 588 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 670 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 589 } | 671 } |
| 590 #if defined(DEBUG) | 672 #if defined(DEBUG) |
| 591 const String& getter_name = String::Handle(Field::GetterName(field_name())); | 673 const String& getter_name = String::Handle(Field::GetterName(field_name_)); |
| 592 const Function& getter = | 674 const Function& getter = |
| 593 Function::Handle(cls().LookupStaticFunction(getter_name)); | 675 Function::Handle(cls().LookupStaticFunction(getter_name)); |
| 594 ASSERT(!getter.IsNull() && | 676 ASSERT(!getter.IsNull() && |
| 595 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); | 677 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); |
| 596 #endif | 678 #endif |
| 597 if (Isolate::Current()->TypeChecksEnabled()) { | 679 if (Isolate::Current()->TypeChecksEnabled()) { |
| 598 rhs = new AssignableNode( | 680 rhs = new AssignableNode( |
| 599 field.token_pos(), | 681 field.token_pos(), |
| 600 rhs, | 682 rhs, |
| 601 AbstractType::ZoneHandle(field.type()), | 683 AbstractType::ZoneHandle(field.type()), |
| 602 String::ZoneHandle(field.name())); | 684 String::ZoneHandle(field.name())); |
| 603 } | 685 } |
| 604 return new StoreStaticFieldNode(token_pos(), field, rhs); | 686 return new StoreStaticFieldNode(token_pos(), field, rhs); |
| 605 } | 687 } |
| 606 // Didn't find a static setter or a static field. Make a call to | 688 // Didn't find a static setter or a static field. Make a call to |
| 607 // the non-existent setter to trigger a NoSuchMethodError at runtime. | 689 // the non-existent setter to trigger a NoSuchMethodError at runtime. |
| 608 return new StaticSetterNode(token_pos(), NULL, cls(), field_name(), rhs); | 690 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 609 } | 691 } |
| 610 | 692 |
| 611 | 693 |
| 612 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { | 694 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { |
| 613 // Return this node if it represents a 'throw NoSuchMethodError' indicating | 695 // Return this node if it represents a 'throw NoSuchMethodError' indicating |
| 614 // that a getter was not found, otherwise return null. | 696 // that a getter was not found, otherwise return null. |
| 615 const Class& cls = Class::Handle(function().Owner()); | 697 const Class& cls = Class::Handle(function().Owner()); |
| 616 const String& cls_name = String::Handle(cls.Name()); | 698 const String& cls_name = String::Handle(cls.Name()); |
| 617 const String& func_name = String::Handle(function().name()); | 699 const String& func_name = String::Handle(function().name()); |
| 618 if (cls_name.Equals(Symbols::NoSuchMethodError()) && | 700 if (cls_name.Equals(Symbols::NoSuchMethodError()) && |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 if (result.IsError() || result.IsNull()) { | 736 if (result.IsError() || result.IsNull()) { |
| 655 // TODO(turnidge): We could get better error messages by returning | 737 // TODO(turnidge): We could get better error messages by returning |
| 656 // the Error object directly to the parser. This will involve | 738 // the Error object directly to the parser. This will involve |
| 657 // replumbing all of the EvalConstExpr methods. | 739 // replumbing all of the EvalConstExpr methods. |
| 658 return NULL; | 740 return NULL; |
| 659 } | 741 } |
| 660 return &Instance::ZoneHandle(Instance::Cast(result).raw()); | 742 return &Instance::ZoneHandle(Instance::Cast(result).raw()); |
| 661 } | 743 } |
| 662 | 744 |
| 663 } // namespace dart | 745 } // namespace dart |
| OLD | NEW |