Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(595)

Side by Side Diff: runtime/vm/parser.cc

Issue 735723003: Implement enum types in VM (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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(&params, current_block_->scope); 1131 AddFormalParamsToScope(&params, 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
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
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
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(&params, 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
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
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
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
OLDNEW
« runtime/vm/method_recognizer.h ('K') | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698