| 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 3790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3801 } else { | 3801 } else { |
| 3802 UnexpectedToken(); | 3802 UnexpectedToken(); |
| 3803 } | 3803 } |
| 3804 current_member_ = NULL; | 3804 current_member_ = NULL; |
| 3805 CheckMemberNameConflict(members, &member); | 3805 CheckMemberNameConflict(members, &member); |
| 3806 members->AddMember(member); | 3806 members->AddMember(member); |
| 3807 } | 3807 } |
| 3808 | 3808 |
| 3809 | 3809 |
| 3810 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 3810 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| 3811 const Class& toplevel_class, |
| 3811 intptr_t metadata_pos) { | 3812 intptr_t metadata_pos) { |
| 3812 TRACE_PARSER("ParseClassDeclaration"); | 3813 TRACE_PARSER("ParseClassDeclaration"); |
| 3813 bool is_patch = false; | 3814 bool is_patch = false; |
| 3814 bool is_abstract = false; | 3815 bool is_abstract = false; |
| 3815 if (is_patch_source() && | 3816 if (is_patch_source() && |
| 3816 (CurrentToken() == Token::kIDENT) && | 3817 (CurrentToken() == Token::kIDENT) && |
| 3817 CurrentLiteral()->Equals("patch")) { | 3818 CurrentLiteral()->Equals("patch")) { |
| 3818 ConsumeToken(); | 3819 ConsumeToken(); |
| 3819 is_patch = true; | 3820 is_patch = true; |
| 3820 } else if (CurrentToken() == Token::kABSTRACT) { | 3821 } else if (CurrentToken() == Token::kABSTRACT) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3903 // We do not check that the bounds are repeated. We use the original ones. | 3904 // We do not check that the bounds are repeated. We use the original ones. |
| 3904 // TODO(regis): Should we check? | 3905 // TODO(regis): Should we check? |
| 3905 } | 3906 } |
| 3906 cls.set_type_parameters(orig_type_parameters); | 3907 cls.set_type_parameters(orig_type_parameters); |
| 3907 } | 3908 } |
| 3908 | 3909 |
| 3909 if (is_abstract) { | 3910 if (is_abstract) { |
| 3910 cls.set_is_abstract(); | 3911 cls.set_is_abstract(); |
| 3911 } | 3912 } |
| 3912 if (metadata_pos >= 0) { | 3913 if (metadata_pos >= 0) { |
| 3913 library_.AddClassMetadata(cls, metadata_pos); | 3914 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 3914 } | 3915 } |
| 3915 | 3916 |
| 3916 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 3917 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
| 3917 if (is_mixin_declaration && is_patch) { | 3918 if (is_mixin_declaration && is_patch) { |
| 3918 ErrorMsg(classname_pos, | 3919 ErrorMsg(classname_pos, |
| 3919 "mixin application '%s' may not be a patch class", | 3920 "mixin application '%s' may not be a patch class", |
| 3920 class_name.ToCString()); | 3921 class_name.ToCString()); |
| 3921 } | 3922 } |
| 3922 | 3923 |
| 3923 AbstractType& super_type = Type::Handle(); | 3924 AbstractType& super_type = Type::Handle(); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4102 // compiled. | 4103 // compiled. |
| 4103 ctors.Add(member); | 4104 ctors.Add(member); |
| 4104 member = class_desc->LookupMember(*member->redirect_name); | 4105 member = class_desc->LookupMember(*member->redirect_name); |
| 4105 } | 4106 } |
| 4106 } | 4107 } |
| 4107 } | 4108 } |
| 4108 | 4109 |
| 4109 | 4110 |
| 4110 void Parser::ParseMixinAppAlias( | 4111 void Parser::ParseMixinAppAlias( |
| 4111 const GrowableObjectArray& pending_classes, | 4112 const GrowableObjectArray& pending_classes, |
| 4113 const Class& toplevel_class, |
| 4112 intptr_t metadata_pos) { | 4114 intptr_t metadata_pos) { |
| 4113 TRACE_PARSER("ParseMixinAppAlias"); | 4115 TRACE_PARSER("ParseMixinAppAlias"); |
| 4114 const intptr_t classname_pos = TokenPos(); | 4116 const intptr_t classname_pos = TokenPos(); |
| 4115 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4117 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4116 if (FLAG_trace_parser) { | 4118 if (FLAG_trace_parser) { |
| 4117 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4119 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 4118 class_name.ToCString()); | 4120 class_name.ToCString()); |
| 4119 } | 4121 } |
| 4120 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 4122 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 4121 if (!obj.IsNull()) { | 4123 if (!obj.IsNull()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4154 | 4156 |
| 4155 // This mixin application alias needs an implicit constructor, but it is | 4157 // This mixin application alias needs an implicit constructor, but it is |
| 4156 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4158 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| 4157 // because this class should be lazily compiled. | 4159 // because this class should be lazily compiled. |
| 4158 if (CurrentToken() == Token::kIMPLEMENTS) { | 4160 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 4159 ParseInterfaceList(mixin_application); | 4161 ParseInterfaceList(mixin_application); |
| 4160 } | 4162 } |
| 4161 ExpectSemicolon(); | 4163 ExpectSemicolon(); |
| 4162 pending_classes.Add(mixin_application, Heap::kOld); | 4164 pending_classes.Add(mixin_application, Heap::kOld); |
| 4163 if (metadata_pos >= 0) { | 4165 if (metadata_pos >= 0) { |
| 4164 library_.AddClassMetadata(mixin_application, metadata_pos); | 4166 library_.AddClassMetadata(mixin_application, toplevel_class, metadata_pos); |
| 4165 } | 4167 } |
| 4166 } | 4168 } |
| 4167 | 4169 |
| 4168 | 4170 |
| 4169 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 4171 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 4170 // We need this lookahead to distinguish between the optional return type | 4172 // We need this lookahead to distinguish between the optional return type |
| 4171 // and the alias name of a function type alias. | 4173 // and the alias name of a function type alias. |
| 4172 // Token position remains unchanged. | 4174 // Token position remains unchanged. |
| 4173 bool Parser::IsFunctionTypeAliasName() { | 4175 bool Parser::IsFunctionTypeAliasName() { |
| 4174 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4176 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4200 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { | 4202 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { |
| 4201 is_mixin_def = true; | 4203 is_mixin_def = true; |
| 4202 } | 4204 } |
| 4203 } | 4205 } |
| 4204 SetPosition(saved_pos); | 4206 SetPosition(saved_pos); |
| 4205 return is_mixin_def; | 4207 return is_mixin_def; |
| 4206 } | 4208 } |
| 4207 | 4209 |
| 4208 | 4210 |
| 4209 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4211 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| 4212 const Class& toplevel_class, |
| 4210 intptr_t metadata_pos) { | 4213 intptr_t metadata_pos) { |
| 4211 TRACE_PARSER("ParseTypedef"); | 4214 TRACE_PARSER("ParseTypedef"); |
| 4212 ExpectToken(Token::kTYPEDEF); | 4215 ExpectToken(Token::kTYPEDEF); |
| 4213 | 4216 |
| 4214 if (IsMixinAppAlias()) { | 4217 if (IsMixinAppAlias()) { |
| 4215 if (FLAG_warn_mixin_typedef) { | 4218 if (FLAG_warn_mixin_typedef) { |
| 4216 Warning("deprecated mixin application typedef"); | 4219 Warning("deprecated mixin application typedef"); |
| 4217 } | 4220 } |
| 4218 ParseMixinAppAlias(pending_classes, metadata_pos); | 4221 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); |
| 4219 return; | 4222 return; |
| 4220 } | 4223 } |
| 4221 | 4224 |
| 4222 // Parse the result type of the function type. | 4225 // Parse the result type of the function type. |
| 4223 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 4226 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 4224 if (CurrentToken() == Token::kVOID) { | 4227 if (CurrentToken() == Token::kVOID) { |
| 4225 ConsumeToken(); | 4228 ConsumeToken(); |
| 4226 result_type = Type::VoidType(); | 4229 result_type = Type::VoidType(); |
| 4227 } else if (!IsFunctionTypeAliasName()) { | 4230 } else if (!IsFunctionTypeAliasName()) { |
| 4228 // Type annotations in typedef are never ignored, even in production mode. | 4231 // Type annotations in typedef are never ignored, even in production mode. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4315 function_type_alias.PatchSignatureFunction(signature_function); | 4318 function_type_alias.PatchSignatureFunction(signature_function); |
| 4316 } | 4319 } |
| 4317 ASSERT(signature_function.signature_class() == signature_class.raw()); | 4320 ASSERT(signature_function.signature_class() == signature_class.raw()); |
| 4318 | 4321 |
| 4319 // The alias should not be marked as finalized yet, since it needs to be | 4322 // The alias should not be marked as finalized yet, since it needs to be |
| 4320 // checked in the class finalizer for illegal self references. | 4323 // checked in the class finalizer for illegal self references. |
| 4321 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); | 4324 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); |
| 4322 ASSERT(!function_type_alias.is_finalized()); | 4325 ASSERT(!function_type_alias.is_finalized()); |
| 4323 pending_classes.Add(function_type_alias, Heap::kOld); | 4326 pending_classes.Add(function_type_alias, Heap::kOld); |
| 4324 if (metadata_pos >= 0) { | 4327 if (metadata_pos >= 0) { |
| 4325 library_.AddClassMetadata(function_type_alias, metadata_pos); | 4328 library_.AddClassMetadata(function_type_alias, |
| 4329 toplevel_class, |
| 4330 metadata_pos); |
| 4326 } | 4331 } |
| 4327 } | 4332 } |
| 4328 | 4333 |
| 4329 | 4334 |
| 4330 // Consumes exactly one right angle bracket. If the current token is a single | 4335 // Consumes exactly one right angle bracket. If the current token is a single |
| 4331 // bracket token, it is consumed normally. However, if it is a double or triple | 4336 // bracket token, it is consumed normally. However, if it is a double or triple |
| 4332 // bracket, it is replaced by a single or double bracket token without | 4337 // bracket, it is replaced by a single or double bracket token without |
| 4333 // incrementing the token index. | 4338 // incrementing the token index. |
| 4334 void Parser::ConsumeRightAngleBracket() { | 4339 void Parser::ConsumeRightAngleBracket() { |
| 4335 if (token_kind_ == Token::kGT) { | 4340 if (token_kind_ == Token::kGT) { |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5175 ParseLibraryDefinition(); | 5180 ParseLibraryDefinition(); |
| 5176 } else if (is_part_source()) { | 5181 } else if (is_part_source()) { |
| 5177 ParsePartHeader(); | 5182 ParsePartHeader(); |
| 5178 } | 5183 } |
| 5179 | 5184 |
| 5180 const Class& cls = Class::Handle(isolate()); | 5185 const Class& cls = Class::Handle(isolate()); |
| 5181 while (true) { | 5186 while (true) { |
| 5182 set_current_class(cls); // No current class. | 5187 set_current_class(cls); // No current class. |
| 5183 intptr_t metadata_pos = SkipMetadata(); | 5188 intptr_t metadata_pos = SkipMetadata(); |
| 5184 if (CurrentToken() == Token::kCLASS) { | 5189 if (CurrentToken() == Token::kCLASS) { |
| 5185 ParseClassDeclaration(pending_classes, metadata_pos); | 5190 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5186 } else if ((CurrentToken() == Token::kTYPEDEF) && | 5191 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 5187 (LookaheadToken(1) != Token::kLPAREN)) { | 5192 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5188 set_current_class(toplevel_class); | 5193 set_current_class(toplevel_class); |
| 5189 ParseTypedef(pending_classes, metadata_pos); | 5194 ParseTypedef(pending_classes, toplevel_class, metadata_pos); |
| 5190 } else if ((CurrentToken() == Token::kABSTRACT) && | 5195 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 5191 (LookaheadToken(1) == Token::kCLASS)) { | 5196 (LookaheadToken(1) == Token::kCLASS)) { |
| 5192 ParseClassDeclaration(pending_classes, metadata_pos); | 5197 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5193 } else if (is_patch_source() && IsLiteral("patch") && | 5198 } else if (is_patch_source() && IsLiteral("patch") && |
| 5194 (LookaheadToken(1) == Token::kCLASS)) { | 5199 (LookaheadToken(1) == Token::kCLASS)) { |
| 5195 ParseClassDeclaration(pending_classes, metadata_pos); | 5200 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5196 } else { | 5201 } else { |
| 5197 set_current_class(toplevel_class); | 5202 set_current_class(toplevel_class); |
| 5198 if (IsVariableDeclaration()) { | 5203 if (IsVariableDeclaration()) { |
| 5199 ParseTopLevelVariable(&top_level, metadata_pos); | 5204 ParseTopLevelVariable(&top_level, metadata_pos); |
| 5200 } else if (IsFunctionDeclaration()) { | 5205 } else if (IsFunctionDeclaration()) { |
| 5201 ParseTopLevelFunction(&top_level, metadata_pos); | 5206 ParseTopLevelFunction(&top_level, metadata_pos); |
| 5202 } else if (IsTopLevelAccessor()) { | 5207 } else if (IsTopLevelAccessor()) { |
| 5203 ParseTopLevelAccessor(&top_level, metadata_pos); | 5208 ParseTopLevelAccessor(&top_level, metadata_pos); |
| 5204 } else if (CurrentToken() == Token::kEOS) { | 5209 } else if (CurrentToken() == Token::kEOS) { |
| 5205 break; | 5210 break; |
| (...skipping 5659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10865 void Parser::SkipQualIdent() { | 10870 void Parser::SkipQualIdent() { |
| 10866 ASSERT(IsIdentifier()); | 10871 ASSERT(IsIdentifier()); |
| 10867 ConsumeToken(); | 10872 ConsumeToken(); |
| 10868 if (CurrentToken() == Token::kPERIOD) { | 10873 if (CurrentToken() == Token::kPERIOD) { |
| 10869 ConsumeToken(); // Consume the kPERIOD token. | 10874 ConsumeToken(); // Consume the kPERIOD token. |
| 10870 ExpectIdentifier("identifier expected after '.'"); | 10875 ExpectIdentifier("identifier expected after '.'"); |
| 10871 } | 10876 } |
| 10872 } | 10877 } |
| 10873 | 10878 |
| 10874 } // namespace dart | 10879 } // namespace dart |
| OLD | NEW |