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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 2418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2429 | 2429 |
2430 // Parse expressions of instance fields that have an explicit | 2430 // Parse expressions of instance fields that have an explicit |
2431 // initializer expression. | 2431 // initializer expression. |
2432 // The receiver must not be visible to field initializer expressions. | 2432 // The receiver must not be visible to field initializer expressions. |
2433 receiver->set_invisible(true); | 2433 receiver->set_invisible(true); |
2434 GrowableArray<Field*> initialized_fields; | 2434 GrowableArray<Field*> initialized_fields; |
2435 ParseInitializedInstanceFields( | 2435 ParseInitializedInstanceFields( |
2436 current_class(), receiver, &initialized_fields); | 2436 current_class(), receiver, &initialized_fields); |
2437 receiver->set_invisible(false); | 2437 receiver->set_invisible(false); |
2438 | 2438 |
2439 // If the class of this implicit constructor is a mixin typedef class, | 2439 // If the class of this implicit constructor is a mixin application alias, |
2440 // it is a forwarding constructor of the aliased mixin application class. | 2440 // it is a forwarding constructor of the aliased mixin application class. |
2441 // If the class of this implicit constructor is a mixin application class, | 2441 // If the class of this implicit constructor is a mixin application class, |
2442 // it is a forwarding constructor of the mixin. The forwarding | 2442 // it is a forwarding constructor of the mixin. The forwarding |
2443 // constructor initializes the instance fields that have initializer | 2443 // constructor initializes the instance fields that have initializer |
2444 // expressions and then calls the respective super constructor with | 2444 // expressions and then calls the respective super constructor with |
2445 // the same name and number of parameters. | 2445 // the same name and number of parameters. |
2446 ArgumentListNode* forwarding_args = NULL; | 2446 ArgumentListNode* forwarding_args = NULL; |
2447 if (current_class().is_mixin_typedef() || | 2447 if (current_class().is_mixin_app_alias() || |
2448 current_class().IsMixinApplication()) { | 2448 current_class().IsMixinApplication()) { |
2449 // At this point we don't support forwarding constructors | 2449 // At this point we don't support forwarding constructors |
2450 // that have optional parameters because we don't know the default | 2450 // that have optional parameters because we don't know the default |
2451 // values of the optional parameters. We would have to compile the super | 2451 // values of the optional parameters. We would have to compile the super |
2452 // constructor to get the default values. Also, the spec is not clear | 2452 // constructor to get the default values. Also, the spec is not clear |
2453 // whether optional parameters are even allowed in this situation. | 2453 // whether optional parameters are even allowed in this situation. |
2454 // TODO(hausner): Remove this limitation if the language spec indeed | 2454 // TODO(hausner): Remove this limitation if the language spec indeed |
2455 // allows optional parameters. | 2455 // allows optional parameters. |
2456 if (func.HasOptionalParameters()) { | 2456 if (func.HasOptionalParameters()) { |
2457 ErrorMsg(ctor_pos, | 2457 ErrorMsg(ctor_pos, |
(...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3893 ErrorMsg(type_pos, | 3893 ErrorMsg(type_pos, |
3894 "class '%s' may not extend type parameter '%s'", | 3894 "class '%s' may not extend type parameter '%s'", |
3895 class_name.ToCString(), | 3895 class_name.ToCString(), |
3896 String::Handle(super_type.UserVisibleName()).ToCString()); | 3896 String::Handle(super_type.UserVisibleName()).ToCString()); |
3897 } | 3897 } |
3898 // The class finalizer will check whether the super type is malbounded. | 3898 // The class finalizer will check whether the super type is malbounded. |
3899 if (CurrentToken() == Token::kWITH) { | 3899 if (CurrentToken() == Token::kWITH) { |
3900 super_type = ParseMixins(super_type); | 3900 super_type = ParseMixins(super_type); |
3901 } | 3901 } |
3902 if (is_mixin_declaration) { | 3902 if (is_mixin_declaration) { |
3903 cls.set_is_mixin_typedef(); | 3903 cls.set_is_mixin_app_alias(); |
3904 cls.set_is_synthesized_class(); | 3904 cls.set_is_synthesized_class(); |
3905 } | 3905 } |
3906 } else { | 3906 } else { |
3907 // No extends clause: implicitly extend Object, unless Object itself. | 3907 // No extends clause: implicitly extend Object, unless Object itself. |
3908 if (!cls.IsObjectClass()) { | 3908 if (!cls.IsObjectClass()) { |
3909 super_type = Type::ObjectType(); | 3909 super_type = Type::ObjectType(); |
3910 } | 3910 } |
3911 } | 3911 } |
3912 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); | 3912 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); |
3913 cls.set_super_type(super_type); | 3913 cls.set_super_type(super_type); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4050 // which the current one redirects, we ignore the unresolved | 4050 // which the current one redirects, we ignore the unresolved |
4051 // reference. We'll catch it later when the constructor gets | 4051 // reference. We'll catch it later when the constructor gets |
4052 // compiled. | 4052 // compiled. |
4053 ctors.Add(member); | 4053 ctors.Add(member); |
4054 member = class_desc->LookupMember(*member->redirect_name); | 4054 member = class_desc->LookupMember(*member->redirect_name); |
4055 } | 4055 } |
4056 } | 4056 } |
4057 } | 4057 } |
4058 | 4058 |
4059 | 4059 |
4060 void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes, | 4060 void Parser::ParseMixinAppAlias( |
4061 intptr_t metadata_pos) { | 4061 const GrowableObjectArray& pending_classes, |
4062 TRACE_PARSER("ParseMixinTypedef"); | 4062 intptr_t metadata_pos) { |
| 4063 TRACE_PARSER("ParseMixinAppAlias"); |
4063 const intptr_t classname_pos = TokenPos(); | 4064 const intptr_t classname_pos = TokenPos(); |
4064 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4065 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
4065 if (FLAG_trace_parser) { | 4066 if (FLAG_trace_parser) { |
4066 OS::Print("toplevel parsing typedef class '%s'\n", class_name.ToCString()); | 4067 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 4068 class_name.ToCString()); |
4067 } | 4069 } |
4068 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 4070 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
4069 if (!obj.IsNull()) { | 4071 if (!obj.IsNull()) { |
4070 ErrorMsg(classname_pos, "'%s' is already defined", | 4072 ErrorMsg(classname_pos, "'%s' is already defined", |
4071 class_name.ToCString()); | 4073 class_name.ToCString()); |
4072 } | 4074 } |
4073 const Class& mixin_application = | 4075 const Class& mixin_application = |
4074 Class::Handle(Class::New(class_name, script_, classname_pos)); | 4076 Class::Handle(Class::New(class_name, script_, classname_pos)); |
4075 mixin_application.set_is_mixin_typedef(); | 4077 mixin_application.set_is_mixin_app_alias(); |
4076 library_.AddClass(mixin_application); | 4078 library_.AddClass(mixin_application); |
4077 set_current_class(mixin_application); | 4079 set_current_class(mixin_application); |
4078 ParseTypeParameters(mixin_application); | 4080 ParseTypeParameters(mixin_application); |
4079 | 4081 |
4080 ExpectToken(Token::kASSIGN); | 4082 ExpectToken(Token::kASSIGN); |
4081 | 4083 |
4082 if (CurrentToken() == Token::kABSTRACT) { | 4084 if (CurrentToken() == Token::kABSTRACT) { |
4083 mixin_application.set_is_abstract(); | 4085 mixin_application.set_is_abstract(); |
4084 ConsumeToken(); | 4086 ConsumeToken(); |
4085 } | 4087 } |
4086 | 4088 |
4087 const intptr_t type_pos = TokenPos(); | 4089 const intptr_t type_pos = TokenPos(); |
4088 AbstractType& type = | 4090 AbstractType& type = |
4089 AbstractType::Handle(ParseType(ClassFinalizer::kResolveTypeParameters)); | 4091 AbstractType::Handle(ParseType(ClassFinalizer::kResolveTypeParameters)); |
4090 if (type.IsTypeParameter()) { | 4092 if (type.IsTypeParameter()) { |
4091 ErrorMsg(type_pos, | 4093 ErrorMsg(type_pos, |
4092 "class '%s' may not extend type parameter '%s'", | 4094 "class '%s' may not extend type parameter '%s'", |
4093 class_name.ToCString(), | 4095 class_name.ToCString(), |
4094 String::Handle(type.UserVisibleName()).ToCString()); | 4096 String::Handle(type.UserVisibleName()).ToCString()); |
4095 } | 4097 } |
4096 | 4098 |
4097 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4099 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
4098 type = ParseMixins(type); | 4100 type = ParseMixins(type); |
4099 | 4101 |
4100 mixin_application.set_super_type(type); | 4102 mixin_application.set_super_type(type); |
4101 mixin_application.set_is_synthesized_class(); | 4103 mixin_application.set_is_synthesized_class(); |
4102 | 4104 |
4103 // This mixin application typedef needs an implicit constructor, but it is | 4105 // This mixin application alias needs an implicit constructor, but it is |
4104 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4106 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
4105 // because this class should be lazily compiled. | 4107 // because this class should be lazily compiled. |
4106 if (CurrentToken() == Token::kIMPLEMENTS) { | 4108 if (CurrentToken() == Token::kIMPLEMENTS) { |
4107 ParseInterfaceList(mixin_application); | 4109 ParseInterfaceList(mixin_application); |
4108 } | 4110 } |
4109 ExpectSemicolon(); | 4111 ExpectSemicolon(); |
4110 pending_classes.Add(mixin_application, Heap::kOld); | 4112 pending_classes.Add(mixin_application, Heap::kOld); |
4111 if (metadata_pos >= 0) { | 4113 if (metadata_pos >= 0) { |
4112 library_.AddClassMetadata(mixin_application, metadata_pos); | 4114 library_.AddClassMetadata(mixin_application, metadata_pos); |
4113 } | 4115 } |
(...skipping 16 matching lines...) Expand all Loading... |
4130 is_alias_name = true; | 4132 is_alias_name = true; |
4131 } | 4133 } |
4132 } | 4134 } |
4133 SetPosition(saved_pos); | 4135 SetPosition(saved_pos); |
4134 return is_alias_name; | 4136 return is_alias_name; |
4135 } | 4137 } |
4136 | 4138 |
4137 | 4139 |
4138 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". | 4140 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". |
4139 // Token position remains unchanged. | 4141 // Token position remains unchanged. |
4140 bool Parser::IsMixinTypedef() { | 4142 bool Parser::IsMixinAppAlias() { |
4141 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { | 4143 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { |
4142 return true; | 4144 return true; |
4143 } | 4145 } |
4144 const intptr_t saved_pos = TokenPos(); | 4146 const intptr_t saved_pos = TokenPos(); |
4145 bool is_mixin_def = false; | 4147 bool is_mixin_def = false; |
4146 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4148 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
4147 ConsumeToken(); | 4149 ConsumeToken(); |
4148 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { | 4150 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { |
4149 is_mixin_def = true; | 4151 is_mixin_def = true; |
4150 } | 4152 } |
4151 } | 4153 } |
4152 SetPosition(saved_pos); | 4154 SetPosition(saved_pos); |
4153 return is_mixin_def; | 4155 return is_mixin_def; |
4154 } | 4156 } |
4155 | 4157 |
4156 | 4158 |
4157 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4159 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
4158 intptr_t metadata_pos) { | 4160 intptr_t metadata_pos) { |
4159 TRACE_PARSER("ParseTypedef"); | 4161 TRACE_PARSER("ParseTypedef"); |
4160 ExpectToken(Token::kTYPEDEF); | 4162 ExpectToken(Token::kTYPEDEF); |
4161 | 4163 |
4162 if (IsMixinTypedef()) { | 4164 if (IsMixinAppAlias()) { |
4163 if (FLAG_warn_mixin_typedef) { | 4165 if (FLAG_warn_mixin_typedef) { |
4164 Warning("deprecated mixin typedef"); | 4166 Warning("deprecated mixin application typedef"); |
4165 } | 4167 } |
4166 ParseMixinTypedef(pending_classes, metadata_pos); | 4168 ParseMixinAppAlias(pending_classes, metadata_pos); |
4167 return; | 4169 return; |
4168 } | 4170 } |
4169 | 4171 |
4170 // Parse the result type of the function type. | 4172 // Parse the result type of the function type. |
4171 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 4173 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
4172 if (CurrentToken() == Token::kVOID) { | 4174 if (CurrentToken() == Token::kVOID) { |
4173 ConsumeToken(); | 4175 ConsumeToken(); |
4174 result_type = Type::VoidType(); | 4176 result_type = Type::VoidType(); |
4175 } else if (!IsFunctionTypeAliasName()) { | 4177 } else if (!IsFunctionTypeAliasName()) { |
4176 // Type annotations in typedef are never ignored, even in unchecked mode. | 4178 // Type annotations in typedef are never ignored, even in production mode. |
4177 // Wait until we have an owner class before resolving the result type. | 4179 // Wait until we have an owner class before resolving the result type. |
4178 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4180 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
4179 } | 4181 } |
4180 | 4182 |
4181 const intptr_t alias_name_pos = TokenPos(); | 4183 const intptr_t alias_name_pos = TokenPos(); |
4182 const String* alias_name = | 4184 const String* alias_name = |
4183 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4185 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
4184 | 4186 |
4185 // Lookup alias name and report an error if it is already defined in | 4187 // Lookup alias name and report an error if it is already defined in |
4186 // the library scope. | 4188 // the library scope. |
(...skipping 6602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10789 void Parser::SkipQualIdent() { | 10791 void Parser::SkipQualIdent() { |
10790 ASSERT(IsIdentifier()); | 10792 ASSERT(IsIdentifier()); |
10791 ConsumeToken(); | 10793 ConsumeToken(); |
10792 if (CurrentToken() == Token::kPERIOD) { | 10794 if (CurrentToken() == Token::kPERIOD) { |
10793 ConsumeToken(); // Consume the kPERIOD token. | 10795 ConsumeToken(); // Consume the kPERIOD token. |
10794 ExpectIdentifier("identifier expected after '.'"); | 10796 ExpectIdentifier("identifier expected after '.'"); |
10795 } | 10797 } |
10796 } | 10798 } |
10797 | 10799 |
10798 } // namespace dart | 10800 } // namespace dart |
OLD | NEW |