Chromium Code Reviews| 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/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 const Script& script) { | 436 const Script& script) { |
| 437 Isolate* isolate = Isolate::Current(); | 437 Isolate* isolate = Isolate::Current(); |
| 438 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 438 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 439 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 439 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 440 VMTagScope tagScope(isolate, VMTag::kCompileTopLevelTagId); | 440 VMTagScope tagScope(isolate, VMTag::kCompileTopLevelTagId); |
| 441 Parser parser(script, library, 0); | 441 Parser parser(script, library, 0); |
| 442 parser.ParseTopLevel(); | 442 parser.ParseTopLevel(); |
| 443 } | 443 } |
| 444 | 444 |
| 445 | 445 |
| 446 intptr_t Parser::FindLibraryDeclarationPosition(const Library& library, | |
| 447 const Script& script) { | |
| 448 Isolate* isolate = Isolate::Current(); | |
| 449 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | |
| 450 Parser parser(script, library, 0); | |
| 451 return parser.GetLibraryDeclarationPosition(); | |
| 452 } | |
| 453 | |
| 454 | |
| 446 void Parser::ComputeCurrentToken() { | 455 void Parser::ComputeCurrentToken() { |
| 447 ASSERT(token_kind_ == Token::kILLEGAL); | 456 ASSERT(token_kind_ == Token::kILLEGAL); |
| 448 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 457 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 449 if (token_kind_ == Token::kERROR) { | 458 if (token_kind_ == Token::kERROR) { |
| 450 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 459 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
| 451 } | 460 } |
| 452 } | 461 } |
| 453 | 462 |
| 454 | 463 |
| 455 Token::Kind Parser::LookaheadToken(int num_tokens) { | 464 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| (...skipping 3695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4151 current_member_ = NULL; | 4160 current_member_ = NULL; |
| 4152 CheckMemberNameConflict(members, &member); | 4161 CheckMemberNameConflict(members, &member); |
| 4153 members->AddMember(member); | 4162 members->AddMember(member); |
| 4154 } | 4163 } |
| 4155 | 4164 |
| 4156 | 4165 |
| 4157 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, | 4166 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
| 4158 const Class& toplevel_class, | 4167 const Class& toplevel_class, |
| 4159 intptr_t metadata_pos) { | 4168 intptr_t metadata_pos) { |
| 4160 TRACE_PARSER("ParseEnumDeclaration"); | 4169 TRACE_PARSER("ParseEnumDeclaration"); |
| 4170 const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos | |
| 4171 : TokenPos(); | |
| 4161 ConsumeToken(); | 4172 ConsumeToken(); |
| 4162 const intptr_t enum_pos = TokenPos(); | 4173 const intptr_t name_pos = TokenPos(); |
| 4163 String* enum_name = | 4174 String* enum_name = |
| 4164 ExpectUserDefinedTypeIdentifier("enum type name expected"); | 4175 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
| 4165 if (FLAG_trace_parser) { | 4176 if (FLAG_trace_parser) { |
| 4166 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); | 4177 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); |
| 4167 } | 4178 } |
| 4168 ExpectToken(Token::kLBRACE); | 4179 ExpectToken(Token::kLBRACE); |
| 4169 if (!IsIdentifier()) { | 4180 if (!IsIdentifier()) { |
| 4170 ReportError("Enumeration must have at least one name"); | 4181 ReportError("Enumeration must have at least one name"); |
| 4171 } | 4182 } |
| 4172 while (IsIdentifier()) { | 4183 while (IsIdentifier()) { |
| 4173 ConsumeToken(); | 4184 ConsumeToken(); |
| 4174 if (CurrentToken() == Token::kCOMMA) { | 4185 if (CurrentToken() == Token::kCOMMA) { |
| 4175 ConsumeToken(); | 4186 ConsumeToken(); |
| 4176 if (CurrentToken() == Token::kRBRACE) { | 4187 if (CurrentToken() == Token::kRBRACE) { |
| 4177 break; | 4188 break; |
| 4178 } | 4189 } |
| 4179 } else if (CurrentToken() == Token::kRBRACE) { | 4190 } else if (CurrentToken() == Token::kRBRACE) { |
| 4180 break; | 4191 break; |
| 4181 } else { | 4192 } else { |
| 4182 ReportError(", or } expected"); | 4193 ReportError(", or } expected"); |
| 4183 } | 4194 } |
| 4184 } | 4195 } |
| 4185 ExpectToken(Token::kRBRACE); | 4196 ExpectToken(Token::kRBRACE); |
| 4186 | 4197 |
| 4187 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); | 4198 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); |
| 4188 if (!obj.IsNull()) { | 4199 if (!obj.IsNull()) { |
| 4189 ReportError(enum_pos, "'%s' is already defined", enum_name->ToCString()); | 4200 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); |
| 4190 } | 4201 } |
| 4191 Class& cls = Class::Handle(Z); | 4202 Class& cls = Class::Handle(Z); |
| 4192 cls = Class::New(*enum_name, script_, enum_pos); | 4203 cls = Class::New(*enum_name, script_, declaration_pos); |
| 4193 cls.set_library(library_); | 4204 cls.set_library(library_); |
| 4194 library_.AddClass(cls); | 4205 library_.AddClass(cls); |
| 4195 cls.set_is_synthesized_class(); | 4206 cls.set_is_synthesized_class(); |
| 4196 cls.set_is_enum_class(); | 4207 cls.set_is_enum_class(); |
| 4197 if (metadata_pos >= 0) { | 4208 if (metadata_pos >= 0) { |
| 4198 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); | 4209 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 4199 } | 4210 } |
| 4200 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); | 4211 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
| 4201 pending_classes.Add(cls, Heap::kOld); | 4212 pending_classes.Add(cls, Heap::kOld); |
| 4202 } | 4213 } |
| 4203 | 4214 |
| 4204 | 4215 |
| 4205 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4216 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| 4206 const Class& toplevel_class, | 4217 const Class& toplevel_class, |
| 4207 intptr_t metadata_pos) { | 4218 intptr_t metadata_pos) { |
| 4208 TRACE_PARSER("ParseClassDeclaration"); | 4219 TRACE_PARSER("ParseClassDeclaration"); |
| 4209 bool is_patch = false; | 4220 bool is_patch = false; |
| 4210 bool is_abstract = false; | 4221 bool is_abstract = false; |
| 4222 intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos(); | |
| 4211 if (is_patch_source() && | 4223 if (is_patch_source() && |
| 4212 (CurrentToken() == Token::kIDENT) && | 4224 (CurrentToken() == Token::kIDENT) && |
| 4213 CurrentLiteral()->Equals("patch")) { | 4225 CurrentLiteral()->Equals("patch")) { |
| 4214 ConsumeToken(); | 4226 ConsumeToken(); |
| 4215 is_patch = true; | 4227 is_patch = true; |
| 4216 } else if (CurrentToken() == Token::kABSTRACT) { | 4228 } else if (CurrentToken() == Token::kABSTRACT) { |
| 4217 is_abstract = true; | 4229 is_abstract = true; |
| 4218 ConsumeToken(); | 4230 ConsumeToken(); |
| 4219 } | 4231 } |
| 4220 ExpectToken(Token::kCLASS); | 4232 ExpectToken(Token::kCLASS); |
| 4221 const intptr_t classname_pos = TokenPos(); | 4233 const intptr_t classname_pos = TokenPos(); |
| 4222 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4234 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4223 if (FLAG_trace_parser) { | 4235 if (FLAG_trace_parser) { |
| 4224 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 4236 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 4225 } | 4237 } |
| 4226 Class& cls = Class::Handle(Z); | 4238 Class& cls = Class::Handle(Z); |
| 4227 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); | 4239 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); |
| 4228 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4240 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
| 4229 if (obj.IsNull()) { | 4241 if (obj.IsNull()) { |
| 4230 if (is_patch) { | 4242 if (is_patch) { |
| 4231 ReportError(classname_pos, "missing class '%s' cannot be patched", | 4243 ReportError(classname_pos, "missing class '%s' cannot be patched", |
| 4232 class_name.ToCString()); | 4244 class_name.ToCString()); |
| 4233 } | 4245 } |
| 4234 cls = Class::New(class_name, script_, classname_pos); | 4246 cls = Class::New(class_name, script_, declaration_pos); |
| 4235 library_.AddClass(cls); | 4247 library_.AddClass(cls); |
| 4236 } else { | 4248 } else { |
| 4237 if (!obj.IsClass()) { | 4249 if (!obj.IsClass()) { |
| 4238 ReportError(classname_pos, "'%s' is already defined", | 4250 ReportError(classname_pos, "'%s' is already defined", |
| 4239 class_name.ToCString()); | 4251 class_name.ToCString()); |
| 4240 } | 4252 } |
| 4241 cls ^= obj.raw(); | 4253 cls ^= obj.raw(); |
| 4242 if (is_patch) { | 4254 if (is_patch) { |
| 4243 // Preserve and reuse the original type parameters and bounds since the | 4255 // Preserve and reuse the original type parameters and bounds since the |
| 4244 // ones defined in the patch class will not be finalized. | 4256 // ones defined in the patch class will not be finalized. |
| 4245 orig_type_parameters = cls.type_parameters(); | 4257 orig_type_parameters = cls.type_parameters(); |
| 4246 // A patch class must be given the same name as the class it is patching, | 4258 // A patch class must be given the same name as the class it is patching, |
| 4247 // otherwise the generic signature classes it defines will not match the | 4259 // otherwise the generic signature classes it defines will not match the |
| 4248 // patched generic signature classes. Therefore, new signature classes | 4260 // patched generic signature classes. Therefore, new signature classes |
| 4249 // will be introduced and the original ones will not get finalized. | 4261 // will be introduced and the original ones will not get finalized. |
| 4250 cls = Class::New(class_name, script_, classname_pos); | 4262 cls = Class::New(class_name, script_, declaration_pos); |
| 4251 cls.set_library(library_); | 4263 cls.set_library(library_); |
| 4252 } else { | 4264 } else { |
| 4253 // Not patching a class, but it has been found. This must be one of the | 4265 // Not patching a class, but it has been found. This must be one of the |
| 4254 // pre-registered classes from object.cc or a duplicate definition. | 4266 // pre-registered classes from object.cc or a duplicate definition. |
| 4255 if (!(cls.is_prefinalized() || | 4267 if (!(cls.is_prefinalized() || |
| 4256 RawObject::IsImplicitFieldClassId(cls.id()))) { | 4268 RawObject::IsImplicitFieldClassId(cls.id()))) { |
| 4257 ReportError(classname_pos, "class '%s' is already defined", | 4269 ReportError(classname_pos, "class '%s' is already defined", |
| 4258 class_name.ToCString()); | 4270 class_name.ToCString()); |
| 4259 } | 4271 } |
| 4260 // Pre-registered classes need their scripts connected at this time. | 4272 // Pre-registered classes need their scripts connected at this time. |
| 4261 cls.set_script(script_); | 4273 cls.set_script(script_); |
| 4262 cls.set_token_pos(classname_pos); | 4274 cls.set_token_pos(declaration_pos); |
| 4263 } | 4275 } |
| 4264 } | 4276 } |
| 4265 ASSERT(!cls.IsNull()); | 4277 ASSERT(!cls.IsNull()); |
| 4266 ASSERT(cls.functions() == Object::empty_array().raw()); | 4278 ASSERT(cls.functions() == Object::empty_array().raw()); |
| 4267 set_current_class(cls); | 4279 set_current_class(cls); |
| 4268 ParseTypeParameters(cls); | 4280 ParseTypeParameters(cls); |
| 4269 if (is_patch) { | 4281 if (is_patch) { |
| 4270 // Check that the new type parameters are identical to the original ones. | 4282 // Check that the new type parameters are identical to the original ones. |
| 4271 const TypeArguments& new_type_parameters = | 4283 const TypeArguments& new_type_parameters = |
| 4272 TypeArguments::Handle(Z, cls.type_parameters()); | 4284 TypeArguments::Handle(Z, cls.type_parameters()); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4392 } | 4404 } |
| 4393 } | 4405 } |
| 4394 | 4406 |
| 4395 | 4407 |
| 4396 void Parser::ParseClassDefinition(const Class& cls) { | 4408 void Parser::ParseClassDefinition(const Class& cls) { |
| 4397 TRACE_PARSER("ParseClassDefinition"); | 4409 TRACE_PARSER("ParseClassDefinition"); |
| 4398 CompilerStats::num_classes_compiled++; | 4410 CompilerStats::num_classes_compiled++; |
| 4399 set_current_class(cls); | 4411 set_current_class(cls); |
| 4400 is_top_level_ = true; | 4412 is_top_level_ = true; |
| 4401 String& class_name = String::Handle(Z, cls.Name()); | 4413 String& class_name = String::Handle(Z, cls.Name()); |
| 4414 SkipMetadata(); | |
| 4415 if (is_patch_source() && | |
| 4416 (CurrentToken() == Token::kIDENT) && | |
| 4417 CurrentLiteral()->Equals("patch")) { | |
| 4418 ConsumeToken(); | |
| 4419 } else if (CurrentToken() == Token::kABSTRACT) { | |
| 4420 ConsumeToken(); | |
| 4421 } | |
| 4422 ExpectToken(Token::kCLASS); | |
| 4402 const intptr_t class_pos = TokenPos(); | 4423 const intptr_t class_pos = TokenPos(); |
| 4403 ClassDesc members(cls, class_name, false, class_pos); | 4424 ClassDesc members(cls, class_name, false, class_pos); |
| 4404 while (CurrentToken() != Token::kLBRACE) { | 4425 while (CurrentToken() != Token::kLBRACE) { |
| 4405 ConsumeToken(); | 4426 ConsumeToken(); |
| 4406 } | 4427 } |
| 4407 ExpectToken(Token::kLBRACE); | 4428 ExpectToken(Token::kLBRACE); |
| 4408 while (CurrentToken() != Token::kRBRACE) { | 4429 while (CurrentToken() != Token::kRBRACE) { |
| 4409 intptr_t metadata_pos = SkipMetadata(); | 4430 intptr_t metadata_pos = SkipMetadata(); |
| 4410 ParseClassMemberDefinition(&members, metadata_pos); | 4431 ParseClassMemberDefinition(&members, metadata_pos); |
| 4411 } | 4432 } |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 4441 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4462 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
| 4442 } | 4463 } |
| 4443 } | 4464 } |
| 4444 } | 4465 } |
| 4445 | 4466 |
| 4446 | 4467 |
| 4447 void Parser::ParseEnumDefinition(const Class& cls) { | 4468 void Parser::ParseEnumDefinition(const Class& cls) { |
| 4448 TRACE_PARSER("ParseEnumDefinition"); | 4469 TRACE_PARSER("ParseEnumDefinition"); |
| 4449 CompilerStats::num_classes_compiled++; | 4470 CompilerStats::num_classes_compiled++; |
| 4450 | 4471 |
| 4472 SkipMetadata(); | |
| 4473 ExpectToken(Token::kENUM); | |
| 4474 | |
| 4451 const String& enum_name = String::Handle(Z, cls.Name()); | 4475 const String& enum_name = String::Handle(Z, cls.Name()); |
| 4452 ClassDesc enum_members(cls, enum_name, false, cls.token_pos()); | 4476 ClassDesc enum_members(cls, enum_name, false, cls.token_pos()); |
| 4453 | 4477 |
| 4454 // Add instance field 'final int index'. | 4478 // Add instance field 'final int index'. |
| 4455 Field& index_field = Field::ZoneHandle(Z); | 4479 Field& index_field = Field::ZoneHandle(Z); |
| 4456 const Type& int_type = Type::Handle(Z, Type::IntType()); | 4480 const Type& int_type = Type::Handle(Z, Type::IntType()); |
| 4457 const Type& dynamic_type = Type::Handle(Type::DynamicType()); | 4481 const Type& dynamic_type = Type::Handle(Type::DynamicType()); |
| 4458 index_field = Field::New(Symbols::Index(), | 4482 index_field = Field::New(Symbols::Index(), |
| 4459 false, // Not static. | 4483 false, // Not static. |
| 4460 true, // Field is final. | 4484 true, // Field is final. |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4777 } | 4801 } |
| 4778 SetPosition(saved_pos); | 4802 SetPosition(saved_pos); |
| 4779 return is_mixin_def; | 4803 return is_mixin_def; |
| 4780 } | 4804 } |
| 4781 | 4805 |
| 4782 | 4806 |
| 4783 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4807 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| 4784 const Class& toplevel_class, | 4808 const Class& toplevel_class, |
| 4785 intptr_t metadata_pos) { | 4809 intptr_t metadata_pos) { |
| 4786 TRACE_PARSER("ParseTypedef"); | 4810 TRACE_PARSER("ParseTypedef"); |
| 4811 intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos(); | |
| 4787 ExpectToken(Token::kTYPEDEF); | 4812 ExpectToken(Token::kTYPEDEF); |
| 4788 | 4813 |
| 4789 if (IsMixinAppAlias()) { | 4814 if (IsMixinAppAlias()) { |
| 4790 if (FLAG_warn_mixin_typedef) { | 4815 if (FLAG_warn_mixin_typedef) { |
| 4791 ReportWarning(TokenPos(), "deprecated mixin application typedef"); | 4816 ReportWarning(TokenPos(), "deprecated mixin application typedef"); |
| 4792 } | 4817 } |
| 4793 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); | 4818 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); |
| 4794 return; | 4819 return; |
| 4795 } | 4820 } |
| 4796 | 4821 |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 4819 } | 4844 } |
| 4820 | 4845 |
| 4821 // Create the function type alias signature class. It will be linked to its | 4846 // Create the function type alias signature class. It will be linked to its |
| 4822 // signature function after it has been parsed. The type parameters, in order | 4847 // signature function after it has been parsed. The type parameters, in order |
| 4823 // to be properly finalized, need to be associated to this signature class as | 4848 // to be properly finalized, need to be associated to this signature class as |
| 4824 // they are parsed. | 4849 // they are parsed. |
| 4825 const Class& function_type_alias = Class::Handle(Z, | 4850 const Class& function_type_alias = Class::Handle(Z, |
| 4826 Class::NewSignatureClass(*alias_name, | 4851 Class::NewSignatureClass(*alias_name, |
| 4827 Function::Handle(Z), | 4852 Function::Handle(Z), |
| 4828 script_, | 4853 script_, |
| 4829 alias_name_pos)); | 4854 declaration_pos)); |
| 4830 library_.AddClass(function_type_alias); | 4855 library_.AddClass(function_type_alias); |
| 4831 set_current_class(function_type_alias); | 4856 set_current_class(function_type_alias); |
| 4832 // Parse the type parameters of the function type. | 4857 // Parse the type parameters of the function type. |
| 4833 ParseTypeParameters(function_type_alias); | 4858 ParseTypeParameters(function_type_alias); |
| 4834 // At this point, the type parameters have been parsed, so we can resolve the | 4859 // At this point, the type parameters have been parsed, so we can resolve the |
| 4835 // result type. | 4860 // result type. |
| 4836 if (!result_type.IsNull()) { | 4861 if (!result_type.IsNull()) { |
| 4837 ResolveTypeFromClass(function_type_alias, | 4862 ResolveTypeFromClass(function_type_alias, |
| 4838 ClassFinalizer::kResolveTypeParameters, | 4863 ClassFinalizer::kResolveTypeParameters, |
| 4839 &result_type); | 4864 &result_type); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4986 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 5011 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 4987 intptr_t index = 0; | 5012 intptr_t index = 0; |
| 4988 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5013 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
| 4989 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5014 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
| 4990 String& existing_type_parameter_name = String::Handle(Z); | 5015 String& existing_type_parameter_name = String::Handle(Z); |
| 4991 AbstractType& type_parameter_bound = Type::Handle(Z); | 5016 AbstractType& type_parameter_bound = Type::Handle(Z); |
| 4992 do { | 5017 do { |
| 4993 ConsumeToken(); | 5018 ConsumeToken(); |
| 4994 const intptr_t metadata_pos = SkipMetadata(); | 5019 const intptr_t metadata_pos = SkipMetadata(); |
| 4995 const intptr_t type_parameter_pos = TokenPos(); | 5020 const intptr_t type_parameter_pos = TokenPos(); |
| 5021 const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos | |
| 5022 : type_parameter_pos; | |
| 4996 String& type_parameter_name = | 5023 String& type_parameter_name = |
| 4997 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 5024 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| 4998 // Check for duplicate type parameters. | 5025 // Check for duplicate type parameters. |
| 4999 for (intptr_t i = 0; i < index; i++) { | 5026 for (intptr_t i = 0; i < index; i++) { |
| 5000 existing_type_parameter ^= type_parameters_array.At(i); | 5027 existing_type_parameter ^= type_parameters_array.At(i); |
| 5001 existing_type_parameter_name = existing_type_parameter.name(); | 5028 existing_type_parameter_name = existing_type_parameter.name(); |
| 5002 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 5029 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| 5003 ReportError(type_parameter_pos, "duplicate type parameter '%s'", | 5030 ReportError(type_parameter_pos, "duplicate type parameter '%s'", |
| 5004 type_parameter_name.ToCString()); | 5031 type_parameter_name.ToCString()); |
| 5005 } | 5032 } |
| 5006 } | 5033 } |
| 5007 if (CurrentToken() == Token::kEXTENDS) { | 5034 if (CurrentToken() == Token::kEXTENDS) { |
| 5008 ConsumeToken(); | 5035 ConsumeToken(); |
| 5009 // A bound may refer to the owner of the type parameter it applies to, | 5036 // A bound may refer to the owner of the type parameter it applies to, |
| 5010 // i.e. to the class or interface currently being parsed. | 5037 // i.e. to the class or interface currently being parsed. |
| 5011 // Postpone resolution in order to avoid resolving the class and its | 5038 // Postpone resolution in order to avoid resolving the class and its |
| 5012 // type parameters, as they are not fully parsed yet. | 5039 // type parameters, as they are not fully parsed yet. |
| 5013 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 5040 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
| 5014 } else { | 5041 } else { |
| 5015 type_parameter_bound = I->object_store()->object_type(); | 5042 type_parameter_bound = I->object_store()->object_type(); |
| 5016 } | 5043 } |
| 5017 type_parameter = TypeParameter::New(cls, | 5044 type_parameter = TypeParameter::New(cls, |
| 5018 index, | 5045 index, |
| 5019 type_parameter_name, | 5046 type_parameter_name, |
| 5020 type_parameter_bound, | 5047 type_parameter_bound, |
| 5021 type_parameter_pos); | 5048 declaration_pos); |
| 5022 type_parameters_array.Add(type_parameter); | 5049 type_parameters_array.Add(type_parameter); |
| 5023 if (metadata_pos >= 0) { | 5050 if (metadata_pos >= 0) { |
| 5024 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 5051 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
| 5025 } | 5052 } |
| 5026 index++; | 5053 index++; |
| 5027 } while (CurrentToken() == Token::kCOMMA); | 5054 } while (CurrentToken() == Token::kCOMMA); |
| 5028 Token::Kind token = CurrentToken(); | 5055 Token::Kind token = CurrentToken(); |
| 5029 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5056 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 5030 ConsumeRightAngleBracket(); | 5057 ConsumeRightAngleBracket(); |
| 5031 } else { | 5058 } else { |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5766 } | 5793 } |
| 5767 while (CurrentToken() == Token::kPART) { | 5794 while (CurrentToken() == Token::kPART) { |
| 5768 ParseLibraryPart(); | 5795 ParseLibraryPart(); |
| 5769 rewind_pos = TokenPos(); | 5796 rewind_pos = TokenPos(); |
| 5770 metadata_pos = SkipMetadata(); | 5797 metadata_pos = SkipMetadata(); |
| 5771 } | 5798 } |
| 5772 SetPosition(rewind_pos); | 5799 SetPosition(rewind_pos); |
| 5773 } | 5800 } |
| 5774 | 5801 |
| 5775 | 5802 |
| 5803 intptr_t Parser::GetLibraryDeclarationPosition() { | |
|
hausner
2015/02/13 21:02:01
When you look at SkipMetadata, you'll see that thi
rmacnak
2015/02/13 22:57:22
True, I'll do this in mirrors.cc instead.
| |
| 5804 if (CurrentToken() == Token::kSCRIPTTAG) { | |
| 5805 // Nothing to do for script tags except to skip them. | |
| 5806 ConsumeToken(); | |
| 5807 } | |
| 5808 intptr_t metadata_pos = SkipMetadata(); | |
| 5809 if (metadata_pos >= 0) { | |
| 5810 return metadata_pos; | |
| 5811 } | |
| 5812 if (CurrentToken() == Token::kLIBRARY) { | |
| 5813 return TokenPos(); | |
| 5814 } | |
| 5815 return Scanner::kNoSourcePos; | |
|
hausner
2015/02/13 21:02:01
Scanner::kNoSourcePos is unfortunately 0, and a fe
| |
| 5816 } | |
| 5817 | |
| 5818 | |
| 5776 void Parser::ParsePartHeader() { | 5819 void Parser::ParsePartHeader() { |
| 5777 SkipMetadata(); | 5820 SkipMetadata(); |
| 5778 CheckToken(Token::kPART, "'part of' expected"); | 5821 CheckToken(Token::kPART, "'part of' expected"); |
| 5779 ConsumeToken(); | 5822 ConsumeToken(); |
| 5780 if (!IsLiteral("of")) { | 5823 if (!IsLiteral("of")) { |
| 5781 ReportError("'part of' expected"); | 5824 ReportError("'part of' expected"); |
| 5782 } | 5825 } |
| 5783 ConsumeToken(); | 5826 ConsumeToken(); |
| 5784 // The VM is not required to check that the library name matches the | 5827 // The VM is not required to check that the library name matches the |
| 5785 // name of the current library, so we ignore it. | 5828 // name of the current library, so we ignore it. |
| (...skipping 6761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12547 void Parser::SkipQualIdent() { | 12590 void Parser::SkipQualIdent() { |
| 12548 ASSERT(IsIdentifier()); | 12591 ASSERT(IsIdentifier()); |
| 12549 ConsumeToken(); | 12592 ConsumeToken(); |
| 12550 if (CurrentToken() == Token::kPERIOD) { | 12593 if (CurrentToken() == Token::kPERIOD) { |
| 12551 ConsumeToken(); // Consume the kPERIOD token. | 12594 ConsumeToken(); // Consume the kPERIOD token. |
| 12552 ExpectIdentifier("identifier expected after '.'"); | 12595 ExpectIdentifier("identifier expected after '.'"); |
| 12553 } | 12596 } |
| 12554 } | 12597 } |
| 12555 | 12598 |
| 12556 } // namespace dart | 12599 } // namespace dart |
| OLD | NEW |