| 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/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 3122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3133 } else { | 3133 } else { |
| 3134 // No extends clause: Implicitly extend Object. | 3134 // No extends clause: Implicitly extend Object. |
| 3135 super_type = Type::ObjectType(); | 3135 super_type = Type::ObjectType(); |
| 3136 } | 3136 } |
| 3137 ASSERT(!super_type.IsNull()); | 3137 ASSERT(!super_type.IsNull()); |
| 3138 cls.set_super_type(super_type); | 3138 cls.set_super_type(super_type); |
| 3139 | 3139 |
| 3140 if (CurrentToken() == Token::kIMPLEMENTS) { | 3140 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3141 Array& interfaces = Array::Handle(); | 3141 Array& interfaces = Array::Handle(); |
| 3142 const intptr_t interfaces_pos = TokenPos(); | 3142 const intptr_t interfaces_pos = TokenPos(); |
| 3143 interfaces = ParseInterfaceList(); | 3143 interfaces = ParseInterfaceList(super_type); |
| 3144 AddInterfaces(interfaces_pos, cls, interfaces); | 3144 AddInterfaces(interfaces_pos, cls, interfaces); |
| 3145 } | 3145 } |
| 3146 | 3146 |
| 3147 ExpectToken(Token::kLBRACE); | 3147 ExpectToken(Token::kLBRACE); |
| 3148 ClassDesc members(cls, class_name, false, class_pos); | 3148 ClassDesc members(cls, class_name, false, class_pos); |
| 3149 while (CurrentToken() != Token::kRBRACE) { | 3149 while (CurrentToken() != Token::kRBRACE) { |
| 3150 SkipMetadata(); | 3150 SkipMetadata(); |
| 3151 ParseClassMemberDefinition(&members); | 3151 ParseClassMemberDefinition(&members); |
| 3152 } | 3152 } |
| 3153 ExpectToken(Token::kRBRACE); | 3153 ExpectToken(Token::kRBRACE); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3559 } | 3559 } |
| 3560 if (finalization != ClassFinalizer::kIgnore) { | 3560 if (finalization != ClassFinalizer::kIgnore) { |
| 3561 return NewTypeArguments(types); | 3561 return NewTypeArguments(types); |
| 3562 } | 3562 } |
| 3563 } | 3563 } |
| 3564 return TypeArguments::null(); | 3564 return TypeArguments::null(); |
| 3565 } | 3565 } |
| 3566 | 3566 |
| 3567 | 3567 |
| 3568 // Parse and return an array of interface types. | 3568 // Parse and return an array of interface types. |
| 3569 RawArray* Parser::ParseInterfaceList() { | 3569 RawArray* Parser::ParseInterfaceList(const Type& super_type) { |
| 3570 TRACE_PARSER("ParseInterfaceList"); | 3570 TRACE_PARSER("ParseInterfaceList"); |
| 3571 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 3571 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || |
| 3572 (CurrentToken() == Token::kEXTENDS)); | 3572 (CurrentToken() == Token::kEXTENDS)); |
| 3573 const GrowableObjectArray& interfaces = | 3573 const GrowableObjectArray& interfaces = |
| 3574 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3574 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3575 String& interface_name = String::Handle(); | 3575 String& interface_name = String::Handle(); |
| 3576 AbstractType& interface = AbstractType::Handle(); | 3576 AbstractType& interface = AbstractType::Handle(); |
| 3577 String& other_name = String::Handle(); | 3577 String& other_name = String::Handle(); |
| 3578 AbstractType& other_interface = AbstractType::Handle(); | 3578 AbstractType& other_interface = AbstractType::Handle(); |
| 3579 const String& super_type_name = String::Handle(super_type.Name()); |
| 3579 do { | 3580 do { |
| 3580 ConsumeToken(); | 3581 ConsumeToken(); |
| 3581 intptr_t interface_pos = TokenPos(); | 3582 intptr_t interface_pos = TokenPos(); |
| 3582 interface = ParseType(ClassFinalizer::kTryResolve); | 3583 interface = ParseType(ClassFinalizer::kTryResolve); |
| 3583 interface_name = interface.UserVisibleName(); | 3584 interface_name = interface.UserVisibleName(); |
| 3585 if (interface_name.Equals(super_type_name)) { |
| 3586 ErrorMsg(interface_pos, "class may not extend and implement '%s'", |
| 3587 interface_name.ToCString()); |
| 3588 } |
| 3584 for (int i = 0; i < interfaces.Length(); i++) { | 3589 for (int i = 0; i < interfaces.Length(); i++) { |
| 3585 other_interface ^= interfaces.At(i); | 3590 other_interface ^= interfaces.At(i); |
| 3586 other_name = other_interface.UserVisibleName(); | 3591 other_name = other_interface.Name(); |
| 3587 if (interface_name.Equals(other_name)) { | 3592 if (interface_name.Equals(other_name)) { |
| 3588 ErrorMsg(interface_pos, "duplicate interface '%s'", | 3593 ErrorMsg(interface_pos, "duplicate interface '%s'", |
| 3589 interface_name.ToCString()); | 3594 interface_name.ToCString()); |
| 3590 } | 3595 } |
| 3591 } | 3596 } |
| 3592 interfaces.Add(interface); | 3597 interfaces.Add(interface); |
| 3593 } while (CurrentToken() == Token::kCOMMA); | 3598 } while (CurrentToken() == Token::kCOMMA); |
| 3594 return Array::MakeArray(interfaces); | 3599 return Array::MakeArray(interfaces); |
| 3595 } | 3600 } |
| 3596 | 3601 |
| 3597 | 3602 |
| 3598 // Add 'interface' to 'interface_list' if it is not already in the list. | 3603 // Add 'interface' to 'interface_list' if it is not already in the list. |
| 3599 // An error is reported if the interface conflicts with an interface already in | 3604 // An error is reported if the interface conflicts with an interface already in |
| 3600 // the list with the same class, but different type arguments. | 3605 // the list with the same class and same type arguments. |
| 3601 // Non-conflicting duplicates are ignored without error. | |
| 3602 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, | 3606 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, |
| 3603 const GrowableObjectArray& interface_list, | 3607 const GrowableObjectArray& interface_list, |
| 3604 const AbstractType& interface) { | 3608 const AbstractType& interface) { |
| 3605 String& interface_class_name = String::Handle(interface.ClassName()); | 3609 String& interface_name = String::Handle(interface.Name()); |
| 3606 String& existing_interface_class_name = String::Handle(); | |
| 3607 String& interface_name = String::Handle(); | |
| 3608 String& existing_interface_name = String::Handle(); | 3610 String& existing_interface_name = String::Handle(); |
| 3609 AbstractType& other_interface = AbstractType::Handle(); | 3611 AbstractType& other_interface = AbstractType::Handle(); |
| 3610 for (intptr_t i = 0; i < interface_list.Length(); i++) { | 3612 for (intptr_t i = 0; i < interface_list.Length(); i++) { |
| 3611 other_interface ^= interface_list.At(i); | 3613 other_interface ^= interface_list.At(i); |
| 3612 existing_interface_class_name = other_interface.ClassName(); | 3614 existing_interface_name = other_interface.Name(); |
| 3613 if (interface_class_name.Equals(existing_interface_class_name)) { | 3615 if (interface_name.Equals(existing_interface_name)) { |
| 3614 // Same interface class name, now check names of type arguments. | 3616 return; |
| 3615 interface_name = interface.Name(); | |
| 3616 existing_interface_name = other_interface.Name(); | |
| 3617 // TODO(regis): Revisit depending on the outcome of issue 4905685. | |
| 3618 if (!interface_name.Equals(existing_interface_name)) { | |
| 3619 ErrorMsg(interfaces_pos, | |
| 3620 "interface '%s' conflicts with interface '%s'", | |
| 3621 String::Handle(interface.UserVisibleName()).ToCString(), | |
| 3622 String::Handle(other_interface.UserVisibleName()).ToCString()); | |
| 3623 } | |
| 3624 } | 3617 } |
| 3625 } | 3618 } |
| 3626 interface_list.Add(interface); | 3619 interface_list.Add(interface); |
| 3627 } | 3620 } |
| 3628 | 3621 |
| 3629 | 3622 |
| 3630 void Parser::AddInterfaces(intptr_t interfaces_pos, | 3623 void Parser::AddInterfaces(intptr_t interfaces_pos, |
| 3631 const Class& cls, | 3624 const Class& cls, |
| 3632 const Array& interfaces) { | 3625 const Array& interfaces) { |
| 3633 const GrowableObjectArray& all_interfaces = | 3626 const GrowableObjectArray& all_interfaces = |
| (...skipping 6069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9703 void Parser::SkipQualIdent() { | 9696 void Parser::SkipQualIdent() { |
| 9704 ASSERT(IsIdentifier()); | 9697 ASSERT(IsIdentifier()); |
| 9705 ConsumeToken(); | 9698 ConsumeToken(); |
| 9706 if (CurrentToken() == Token::kPERIOD) { | 9699 if (CurrentToken() == Token::kPERIOD) { |
| 9707 ConsumeToken(); // Consume the kPERIOD token. | 9700 ConsumeToken(); // Consume the kPERIOD token. |
| 9708 ExpectIdentifier("identifier expected after '.'"); | 9701 ExpectIdentifier("identifier expected after '.'"); |
| 9709 } | 9702 } |
| 9710 } | 9703 } |
| 9711 | 9704 |
| 9712 } // namespace dart | 9705 } // namespace dart |
| OLD | NEW |