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 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 | 725 |
726 void Parser::ParseClass(const Class& cls) { | 726 void Parser::ParseClass(const Class& cls) { |
727 if (!cls.is_synthesized_class()) { | 727 if (!cls.is_synthesized_class()) { |
728 Isolate* isolate = Isolate::Current(); | 728 Isolate* isolate = Isolate::Current(); |
729 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 729 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
730 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 730 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
731 const Script& script = Script::Handle(isolate, cls.script()); | 731 const Script& script = Script::Handle(isolate, cls.script()); |
732 const Library& lib = Library::Handle(isolate, cls.library()); | 732 const Library& lib = Library::Handle(isolate, cls.library()); |
733 Parser parser(script, lib, cls.token_pos()); | 733 Parser parser(script, lib, cls.token_pos()); |
734 parser.ParseClassDefinition(cls); | 734 parser.ParseClassDefinition(cls); |
| 735 } else if (cls.is_enum_class()) { |
| 736 Isolate* isolate = Isolate::Current(); |
| 737 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 738 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 739 const Script& script = Script::Handle(isolate, cls.script()); |
| 740 const Library& lib = Library::Handle(isolate, cls.library()); |
| 741 Parser parser(script, lib, cls.token_pos()); |
| 742 parser.ParseEnumDefinition(cls); |
735 } | 743 } |
736 } | 744 } |
737 | 745 |
738 | 746 |
739 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 747 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
740 ASSERT(!func.IsNull()); | 748 ASSERT(!func.IsNull()); |
741 Isolate* isolate = Isolate::Current(); | 749 Isolate* isolate = Isolate::Current(); |
742 StackZone zone(isolate); | 750 StackZone zone(isolate); |
743 LongJumpScope jump; | 751 LongJumpScope jump; |
744 if (setjmp(*jump.Set()) == 0) { | 752 if (setjmp(*jump.Set()) == 0) { |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1118 ASSERT(!func.HasOptionalParameters()); | 1126 ASSERT(!func.HasOptionalParameters()); |
1119 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 1127 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
1120 | 1128 |
1121 // Build local scope for function and populate with the formal parameters. | 1129 // Build local scope for function and populate with the formal parameters. |
1122 OpenFunctionBlock(func); | 1130 OpenFunctionBlock(func); |
1123 AddFormalParamsToScope(¶ms, current_block_->scope); | 1131 AddFormalParamsToScope(¶ms, current_block_->scope); |
1124 | 1132 |
1125 // Receiver is local 0. | 1133 // Receiver is local 0. |
1126 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1134 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
1127 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1135 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
1128 ASSERT(IsIdentifier()); | 1136 String& field_name = String::Handle(I, func.name()); |
1129 const String& field_name = *CurrentLiteral(); | 1137 field_name = Field::NameFromGetter(field_name); |
| 1138 |
1130 const Class& field_class = Class::Handle(I, func.Owner()); | 1139 const Class& field_class = Class::Handle(I, func.Owner()); |
1131 const Field& field = | 1140 const Field& field = |
1132 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); | 1141 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); |
| 1142 ASSERT(!field.IsNull()); |
1133 | 1143 |
1134 LoadInstanceFieldNode* load_field = | 1144 LoadInstanceFieldNode* load_field = |
1135 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1145 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
1136 | 1146 |
1137 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field); | 1147 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field); |
1138 current_block_->statements->Add(return_node); | 1148 current_block_->statements->Add(return_node); |
1139 return CloseBlock(); | 1149 return CloseBlock(); |
1140 } | 1150 } |
1141 | 1151 |
1142 | 1152 |
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3044 } else if (func.is_async_closure()) { | 3054 } else if (func.is_async_closure()) { |
3045 OpenAsyncClosure(); | 3055 OpenAsyncClosure(); |
3046 } | 3056 } |
3047 | 3057 |
3048 bool saved_await_is_keyword = await_is_keyword_; | 3058 bool saved_await_is_keyword = await_is_keyword_; |
3049 await_is_keyword_ = func.IsAsyncFunction() || func.is_async_closure(); | 3059 await_is_keyword_ = func.IsAsyncFunction() || func.is_async_closure(); |
3050 | 3060 |
3051 intptr_t end_token_pos = 0; | 3061 intptr_t end_token_pos = 0; |
3052 if (CurrentToken() == Token::kLBRACE) { | 3062 if (CurrentToken() == Token::kLBRACE) { |
3053 ConsumeToken(); | 3063 ConsumeToken(); |
3054 if (String::Handle(I, func.name()).Equals( | 3064 if (String::Handle(I, func.name()).Equals(Symbols::EqualOperator())) { |
3055 Symbols::EqualOperator())) { | |
3056 const Class& owner = Class::Handle(I, func.Owner()); | 3065 const Class& owner = Class::Handle(I, func.Owner()); |
3057 if (!owner.IsObjectClass()) { | 3066 if (!owner.IsObjectClass()) { |
3058 AddEqualityNullCheck(); | 3067 AddEqualityNullCheck(); |
3059 } | 3068 } |
3060 } | 3069 } |
3061 ParseStatementSequence(); | 3070 ParseStatementSequence(); |
3062 end_token_pos = TokenPos(); | 3071 end_token_pos = TokenPos(); |
3063 ExpectToken(Token::kRBRACE); | 3072 ExpectToken(Token::kRBRACE); |
3064 } else if (CurrentToken() == Token::kARROW) { | 3073 } else if (CurrentToken() == Token::kARROW) { |
3065 ConsumeToken(); | 3074 ConsumeToken(); |
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3995 ParseFieldDefinition(members, &member); | 4004 ParseFieldDefinition(members, &member); |
3996 } else { | 4005 } else { |
3997 UnexpectedToken(); | 4006 UnexpectedToken(); |
3998 } | 4007 } |
3999 current_member_ = NULL; | 4008 current_member_ = NULL; |
4000 CheckMemberNameConflict(members, &member); | 4009 CheckMemberNameConflict(members, &member); |
4001 members->AddMember(member); | 4010 members->AddMember(member); |
4002 } | 4011 } |
4003 | 4012 |
4004 | 4013 |
| 4014 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
| 4015 const Class& toplevel_class, |
| 4016 intptr_t metadata_pos) { |
| 4017 TRACE_PARSER("ParseEnumDeclaration"); |
| 4018 ConsumeToken(); |
| 4019 const intptr_t enum_pos = TokenPos(); |
| 4020 String* enum_name = |
| 4021 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
| 4022 if (FLAG_trace_parser) { |
| 4023 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); |
| 4024 } |
| 4025 ExpectToken(Token::kLBRACE); |
| 4026 if (!IsIdentifier()) { |
| 4027 ReportError("Enumeration must have at least one name"); |
| 4028 } |
| 4029 while (IsIdentifier()) { |
| 4030 ConsumeToken(); |
| 4031 if (CurrentToken() == Token::kCOMMA) { |
| 4032 ConsumeToken(); |
| 4033 if (CurrentToken() == Token::kRBRACE) { |
| 4034 break; |
| 4035 } |
| 4036 } else if (CurrentToken() == Token::kRBRACE) { |
| 4037 break; |
| 4038 } else { |
| 4039 ReportError(", or } expected"); |
| 4040 } |
| 4041 } |
| 4042 ExpectToken(Token::kRBRACE); |
| 4043 |
| 4044 Object& obj = Object::Handle(I, library_.LookupLocalObject(*enum_name)); |
| 4045 if (!obj.IsNull()) { |
| 4046 ReportError(enum_pos, "'%s' is already defined", enum_name->ToCString()); |
| 4047 } |
| 4048 Class& cls = Class::Handle(I); |
| 4049 cls = Class::New(*enum_name, script_, enum_pos); |
| 4050 cls.set_library(library_); |
| 4051 library_.AddClass(cls); |
| 4052 cls.set_is_synthesized_class(); |
| 4053 cls.set_is_enum_class(); |
| 4054 if (metadata_pos >= 0) { |
| 4055 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 4056 } |
| 4057 cls.set_super_type(Type::Handle(I, Type::ObjectType())); |
| 4058 pending_classes.Add(cls, Heap::kOld); |
| 4059 } |
| 4060 |
| 4061 |
4005 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4062 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
4006 const Class& toplevel_class, | 4063 const Class& toplevel_class, |
4007 intptr_t metadata_pos) { | 4064 intptr_t metadata_pos) { |
4008 TRACE_PARSER("ParseClassDeclaration"); | 4065 TRACE_PARSER("ParseClassDeclaration"); |
4009 bool is_patch = false; | 4066 bool is_patch = false; |
4010 bool is_abstract = false; | 4067 bool is_abstract = false; |
4011 if (is_patch_source() && | 4068 if (is_patch_source() && |
4012 (CurrentToken() == Token::kIDENT) && | 4069 (CurrentToken() == Token::kIDENT) && |
4013 CurrentLiteral()->Equals("patch")) { | 4070 CurrentLiteral()->Equals("patch")) { |
4014 ConsumeToken(); | 4071 ConsumeToken(); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4237 const Class& orig_class = Class::Cast(obj); | 4294 const Class& orig_class = Class::Cast(obj); |
4238 ASSERT(!orig_class.is_finalized()); | 4295 ASSERT(!orig_class.is_finalized()); |
4239 Error& error = Error::Handle(I); | 4296 Error& error = Error::Handle(I); |
4240 if (!orig_class.ApplyPatch(cls, &error)) { | 4297 if (!orig_class.ApplyPatch(cls, &error)) { |
4241 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4298 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
4242 } | 4299 } |
4243 } | 4300 } |
4244 } | 4301 } |
4245 | 4302 |
4246 | 4303 |
| 4304 void Parser::ParseEnumDefinition(const Class& cls) { |
| 4305 TRACE_PARSER("ParseEnumDefinition"); |
| 4306 CompilerStats::num_classes_compiled++; |
| 4307 |
| 4308 const String& enum_name = String::Handle(I, cls.Name()); |
| 4309 ClassDesc enum_members(cls, enum_name, false, cls.token_pos()); |
| 4310 |
| 4311 // Add instance field 'final int index'. |
| 4312 Field& index_field = Field::ZoneHandle(I); |
| 4313 const Type& int_type = Type::Handle(I, Type::IntType()); |
| 4314 const Type& dynamic_type = Type::Handle(Type::DynamicType()); |
| 4315 index_field = Field::New(Symbols::Index(), |
| 4316 false, // Not static. |
| 4317 true, // Field is final. |
| 4318 false, // Not const. |
| 4319 false, // Not synthetic. |
| 4320 cls, |
| 4321 cls.token_pos()); |
| 4322 index_field.set_type(int_type); |
| 4323 enum_members.AddField(index_field); |
| 4324 |
| 4325 // Add implicit getter for index field. |
| 4326 const String& getter_name = |
| 4327 String::Handle(I, Field::GetterSymbol(Symbols::Index())); |
| 4328 Function& getter = Function::Handle(I); |
| 4329 getter = Function::New(getter_name, |
| 4330 RawFunction::kImplicitGetter, |
| 4331 /* is_static = */ false, |
| 4332 /* is_const = */ true, |
| 4333 /* is_abstract = */ false, |
| 4334 /* is_external = */ false, |
| 4335 /* is_native = */ false, |
| 4336 cls, |
| 4337 cls.token_pos()); |
| 4338 getter.set_result_type(int_type); |
| 4339 ParamList params; |
| 4340 params.AddReceiver(&dynamic_type, cls.token_pos()); |
| 4341 AddFormalParamsToFunction(¶ms, getter); |
| 4342 enum_members.AddFunction(getter); |
| 4343 |
| 4344 GrowableObjectArray& enum_names = GrowableObjectArray::Handle(I, |
| 4345 GrowableObjectArray::New(8, Heap::kOld)); |
| 4346 const String& name_prefix = |
| 4347 String::Handle(String::Concat(enum_name, Symbols::Dot())); |
| 4348 |
| 4349 ASSERT(IsIdentifier()); |
| 4350 ASSERT(CurrentLiteral()->raw() == cls.Name()); |
| 4351 |
| 4352 ConsumeToken(); // Enum type name. |
| 4353 ExpectToken(Token::kLBRACE); |
| 4354 Field& enum_value = Field::Handle(I); |
| 4355 String& enum_value_name = String::Handle(I); |
| 4356 intptr_t i = 0; |
| 4357 GrowableArray<String*> declared_names(8); |
| 4358 |
| 4359 while (IsIdentifier()) { |
| 4360 String* enum_ident = CurrentLiteral(); |
| 4361 |
| 4362 // Check for name conflicts. |
| 4363 if (enum_ident->raw() == cls.Name()) { |
| 4364 ReportError("enum identifier '%s' cannot be equal to enum type name", |
| 4365 CurrentLiteral()->ToCString()); |
| 4366 } else if (enum_ident->raw() == Symbols::Index().raw()) { |
| 4367 ReportError("enum identifier conflicts with " |
| 4368 "implicit instance field 'index'"); |
| 4369 } else if (enum_ident->raw() == Symbols::Values().raw()) { |
| 4370 ReportError("enum identifier conflicts with " |
| 4371 "implicit static field 'values'"); |
| 4372 } else if (enum_ident->raw() == Symbols::toString().raw()) { |
| 4373 ReportError("enum identifier conflicts with " |
| 4374 "implicit instance method 'toString()'"); |
| 4375 } |
| 4376 for (intptr_t i = 0; i < declared_names.length(); i++) { |
| 4377 if (enum_ident->Equals(*declared_names[i])) { |
| 4378 ReportError("Duplicate name '%s' in enum definition '%s'", |
| 4379 enum_ident->ToCString(), |
| 4380 enum_name.ToCString()); |
| 4381 } |
| 4382 } |
| 4383 declared_names.Add(enum_ident); |
| 4384 |
| 4385 // Create the static const field for the enumeration value. |
| 4386 enum_value = Field::New(*enum_ident, |
| 4387 /* is_static = */ true, |
| 4388 /* is_final = */ true, |
| 4389 /* is_const = */ true, |
| 4390 /* is_synthetic = */ false, |
| 4391 cls, |
| 4392 cls.token_pos()); |
| 4393 enum_value.set_type(dynamic_type); |
| 4394 enum_value.set_has_initializer(false); |
| 4395 enum_members.AddField(enum_value); |
| 4396 // Initialize the field with the ordinal value. It will be patched |
| 4397 // later with the enum constant instance. |
| 4398 const Smi& ordinal_value = Smi::Handle(I, Smi::New(i)); |
| 4399 enum_value.set_value(ordinal_value); |
| 4400 enum_value.RecordStore(ordinal_value); |
| 4401 i++; |
| 4402 |
| 4403 // For the user-visible name of the enumeration value, we need to |
| 4404 // unmangle private names. |
| 4405 if (enum_ident->CharAt(0) == '_') { |
| 4406 *enum_ident = String::IdentifierPrettyName(*enum_ident); |
| 4407 } |
| 4408 enum_value_name = Symbols::FromConcat(name_prefix, *enum_ident); |
| 4409 enum_names.Add(enum_value_name, Heap::kOld); |
| 4410 |
| 4411 ConsumeToken(); // Enum value name. |
| 4412 if (CurrentToken() == Token::kCOMMA) { |
| 4413 ConsumeToken(); |
| 4414 } |
| 4415 } |
| 4416 ExpectToken(Token::kRBRACE); |
| 4417 |
| 4418 const Class& helper_class = |
| 4419 Class::Handle(I, Library::LookupCoreClass(Symbols::_EnumHelper())); |
| 4420 ASSERT(!helper_class.IsNull()); |
| 4421 |
| 4422 // Add static field 'const List values'. |
| 4423 Field& values_field = Field::ZoneHandle(I); |
| 4424 values_field = Field::New(Symbols::Values(), |
| 4425 /* is_static = */ true, |
| 4426 /* is_final = */ true, |
| 4427 /* is_const = */ true, |
| 4428 /* is_synthetic = */ false, |
| 4429 cls, |
| 4430 cls.token_pos()); |
| 4431 values_field.set_type(Type::Handle(I, Type::ArrayType())); |
| 4432 enum_members.AddField(values_field); |
| 4433 |
| 4434 // Allocate the immutable array containing the enumeration values. |
| 4435 // The actual enum instance values will be patched in later. |
| 4436 const Array& values_array = Array::Handle(I, Array::New(i, Heap::kOld)); |
| 4437 values_field.set_value(values_array); |
| 4438 values_field.RecordStore(values_array); |
| 4439 |
| 4440 // Create a static field that contains the list of enumeration names. |
| 4441 // Clone the _enum_names field from the helper class. |
| 4442 Field& names_field = Field::Handle(I, |
| 4443 helper_class.LookupStaticField(Symbols::_EnumNames())); |
| 4444 ASSERT(!names_field.IsNull()); |
| 4445 names_field = names_field.Clone(cls); |
| 4446 enum_members.AddField(names_field); |
| 4447 const Array& names_array = Array::Handle(Array::MakeArray(enum_names)); |
| 4448 names_field.set_value(names_array); |
| 4449 names_field.RecordStore(names_array); |
| 4450 |
| 4451 // Clone the toString() function from the helper class. |
| 4452 Function& to_string_func = Function::Handle(I, |
| 4453 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); |
| 4454 ASSERT(!to_string_func.IsNull()); |
| 4455 to_string_func = to_string_func.Clone(cls); |
| 4456 to_string_func.set_is_visible(false); |
| 4457 enum_members.AddFunction(to_string_func); |
| 4458 |
| 4459 cls.AddFields(enum_members.fields()); |
| 4460 const Array& functions = |
| 4461 Array::Handle(I, Array::MakeArray(enum_members.functions())); |
| 4462 cls.SetFunctions(functions); |
| 4463 } |
| 4464 |
| 4465 |
4247 // Add an implicit constructor to the given class. | 4466 // Add an implicit constructor to the given class. |
4248 void Parser::AddImplicitConstructor(const Class& cls) { | 4467 void Parser::AddImplicitConstructor(const Class& cls) { |
4249 // The implicit constructor is unnamed, has no explicit parameter. | 4468 // The implicit constructor is unnamed, has no explicit parameter. |
4250 String& ctor_name = String::ZoneHandle(I, cls.Name()); | 4469 String& ctor_name = String::ZoneHandle(I, cls.Name()); |
4251 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 4470 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
4252 ctor_name = Symbols::New(ctor_name); | 4471 ctor_name = Symbols::New(ctor_name); |
4253 // To indicate that this is an implicit constructor, we set the | 4472 // To indicate that this is an implicit constructor, we set the |
4254 // token position and end token position of the function | 4473 // token position and end token position of the function |
4255 // to the token position of the class. | 4474 // to the token position of the class. |
4256 Function& ctor = Function::Handle(I, | 4475 Function& ctor = Function::Handle(I, |
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5419 } else if (is_part_source()) { | 5638 } else if (is_part_source()) { |
5420 ParsePartHeader(); | 5639 ParsePartHeader(); |
5421 } | 5640 } |
5422 | 5641 |
5423 const Class& cls = Class::Handle(I); | 5642 const Class& cls = Class::Handle(I); |
5424 while (true) { | 5643 while (true) { |
5425 set_current_class(cls); // No current class. | 5644 set_current_class(cls); // No current class. |
5426 intptr_t metadata_pos = SkipMetadata(); | 5645 intptr_t metadata_pos = SkipMetadata(); |
5427 if (CurrentToken() == Token::kCLASS) { | 5646 if (CurrentToken() == Token::kCLASS) { |
5428 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); | 5647 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5648 } else if (CurrentToken() == Token::kENUM) { |
| 5649 ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos); |
5429 } else if ((CurrentToken() == Token::kTYPEDEF) && | 5650 } else if ((CurrentToken() == Token::kTYPEDEF) && |
5430 (LookaheadToken(1) != Token::kLPAREN)) { | 5651 (LookaheadToken(1) != Token::kLPAREN)) { |
5431 set_current_class(toplevel_class); | 5652 set_current_class(toplevel_class); |
5432 ParseTypedef(pending_classes, toplevel_class, metadata_pos); | 5653 ParseTypedef(pending_classes, toplevel_class, metadata_pos); |
5433 } else if ((CurrentToken() == Token::kABSTRACT) && | 5654 } else if ((CurrentToken() == Token::kABSTRACT) && |
5434 (LookaheadToken(1) == Token::kCLASS)) { | 5655 (LookaheadToken(1) == Token::kCLASS)) { |
5435 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); | 5656 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
5436 } else if (is_patch_source() && IsLiteral("patch") && | 5657 } else if (is_patch_source() && IsLiteral("patch") && |
5437 (LookaheadToken(1) == Token::kCLASS)) { | 5658 (LookaheadToken(1) == Token::kCLASS)) { |
5438 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); | 5659 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
(...skipping 5540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10979 type = ClassFinalizer::NewFinalizedMalformedType( | 11200 type = ClassFinalizer::NewFinalizedMalformedType( |
10980 Error::Handle(I), // No previous error. | 11201 Error::Handle(I), // No previous error. |
10981 script_, | 11202 script_, |
10982 type_pos, | 11203 type_pos, |
10983 "%s'%s' cannot be instantiated", | 11204 "%s'%s' cannot be instantiated", |
10984 type.IsTypeParameter() ? "type parameter " : "", | 11205 type.IsTypeParameter() ? "type parameter " : "", |
10985 type.IsTypeParameter() ? | 11206 type.IsTypeParameter() ? |
10986 String::Handle(I, type.UserVisibleName()).ToCString() : | 11207 String::Handle(I, type.UserVisibleName()).ToCString() : |
10987 "dynamic"); | 11208 "dynamic"); |
10988 } | 11209 } |
| 11210 // Attempting to instantiate an enum type is a compile-time error. |
| 11211 Class& type_class = Class::Handle(I, type.type_class()); |
| 11212 if (type_class.is_enum_class()) { |
| 11213 ReportError(new_pos, "enum type '%s' can not be instantiated", |
| 11214 String::Handle(I, type_class.Name()).ToCString()); |
| 11215 } |
10989 | 11216 |
10990 // The grammar allows for an optional ('.' identifier)? after the type, which | 11217 // The grammar allows for an optional ('.' identifier)? after the type, which |
10991 // is a named constructor. Note that we tell ParseType() above not to | 11218 // is a named constructor. Note that we tell ParseType() above not to |
10992 // consume it as part of a misinterpreted qualified identifier. Only a | 11219 // consume it as part of a misinterpreted qualified identifier. Only a |
10993 // valid library prefix is accepted as qualifier. | 11220 // valid library prefix is accepted as qualifier. |
10994 String* named_constructor = NULL; | 11221 String* named_constructor = NULL; |
10995 if (CurrentToken() == Token::kPERIOD) { | 11222 if (CurrentToken() == Token::kPERIOD) { |
10996 ConsumeToken(); | 11223 ConsumeToken(); |
10997 named_constructor = ExpectIdentifier("name of constructor expected"); | 11224 named_constructor = ExpectIdentifier("name of constructor expected"); |
10998 } | 11225 } |
10999 | 11226 |
11000 // Parse constructor parameters. | 11227 // Parse constructor parameters. |
11001 CheckToken(Token::kLPAREN); | 11228 CheckToken(Token::kLPAREN); |
11002 intptr_t call_pos = TokenPos(); | 11229 intptr_t call_pos = TokenPos(); |
11003 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 11230 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
11004 | 11231 |
11005 // Parsing is complete, so we can return a throw in case of a malformed or | 11232 // Parsing is complete, so we can return a throw in case of a malformed or |
11006 // malbounded type or report a compile-time error if the constructor is const. | 11233 // malbounded type or report a compile-time error if the constructor is const. |
11007 if (type.IsMalformedOrMalbounded()) { | 11234 if (type.IsMalformedOrMalbounded()) { |
11008 if (is_const) { | 11235 if (is_const) { |
11009 const Error& error = Error::Handle(I, type.error()); | 11236 const Error& error = Error::Handle(I, type.error()); |
11010 ReportError(error); | 11237 ReportError(error); |
11011 } | 11238 } |
11012 return ThrowTypeError(type_pos, type); | 11239 return ThrowTypeError(type_pos, type); |
11013 } | 11240 } |
11014 | 11241 |
11015 // Resolve the type and optional identifier to a constructor or factory. | 11242 // Resolve the type and optional identifier to a constructor or factory. |
11016 Class& type_class = Class::Handle(I, type.type_class()); | |
11017 String& type_class_name = String::Handle(I, type_class.Name()); | 11243 String& type_class_name = String::Handle(I, type_class.Name()); |
11018 TypeArguments& type_arguments = | 11244 TypeArguments& type_arguments = |
11019 TypeArguments::ZoneHandle(I, type.arguments()); | 11245 TypeArguments::ZoneHandle(I, type.arguments()); |
11020 | 11246 |
11021 // A constructor has an implicit 'this' parameter (instance to construct) | 11247 // A constructor has an implicit 'this' parameter (instance to construct) |
11022 // and a factory has an implicit 'this' parameter (type_arguments). | 11248 // and a factory has an implicit 'this' parameter (type_arguments). |
11023 // A constructor has a second implicit 'phase' parameter. | 11249 // A constructor has a second implicit 'phase' parameter. |
11024 intptr_t arguments_length = arguments->length() + 2; | 11250 intptr_t arguments_length = arguments->length() + 2; |
11025 | 11251 |
11026 // An additional type check of the result of a redirecting factory may be | 11252 // An additional type check of the result of a redirecting factory may be |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11892 void Parser::SkipQualIdent() { | 12118 void Parser::SkipQualIdent() { |
11893 ASSERT(IsIdentifier()); | 12119 ASSERT(IsIdentifier()); |
11894 ConsumeToken(); | 12120 ConsumeToken(); |
11895 if (CurrentToken() == Token::kPERIOD) { | 12121 if (CurrentToken() == Token::kPERIOD) { |
11896 ConsumeToken(); // Consume the kPERIOD token. | 12122 ConsumeToken(); // Consume the kPERIOD token. |
11897 ExpectIdentifier("identifier expected after '.'"); | 12123 ExpectIdentifier("identifier expected after '.'"); |
11898 } | 12124 } |
11899 } | 12125 } |
11900 | 12126 |
11901 } // namespace dart | 12127 } // namespace dart |
OLD | NEW |