| 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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 has_static = false; | 524 has_static = false; |
| 525 has_var = false; | 525 has_var = false; |
| 526 has_factory = false; | 526 has_factory = false; |
| 527 has_operator = false; | 527 has_operator = false; |
| 528 metadata_pos = -1; | 528 metadata_pos = -1; |
| 529 operator_token = Token::kILLEGAL; | 529 operator_token = Token::kILLEGAL; |
| 530 type = NULL; | 530 type = NULL; |
| 531 name_pos = 0; | 531 name_pos = 0; |
| 532 name = NULL; | 532 name = NULL; |
| 533 redirect_name = NULL; | 533 redirect_name = NULL; |
| 534 constructor_name = NULL; | 534 dict_name = NULL; |
| 535 params.Clear(); | 535 params.Clear(); |
| 536 kind = RawFunction::kRegularFunction; | 536 kind = RawFunction::kRegularFunction; |
| 537 field_ = NULL; |
| 537 } | 538 } |
| 538 bool IsConstructor() const { | 539 bool IsConstructor() const { |
| 539 return (kind == RawFunction::kConstructor) && !has_static; | 540 return (kind == RawFunction::kConstructor) && !has_static; |
| 540 } | 541 } |
| 541 bool IsFactory() const { | 542 bool IsFactory() const { |
| 542 return (kind == RawFunction::kConstructor) && has_static; | 543 return (kind == RawFunction::kConstructor) && has_static; |
| 543 } | 544 } |
| 544 bool IsFactoryOrConstructor() const { | 545 bool IsFactoryOrConstructor() const { |
| 545 return (kind == RawFunction::kConstructor); | 546 return (kind == RawFunction::kConstructor); |
| 546 } | 547 } |
| 547 bool IsGetter() const { | 548 bool IsGetter() const { |
| 548 return kind == RawFunction::kGetterFunction; | 549 return kind == RawFunction::kGetterFunction; |
| 549 } | 550 } |
| 550 bool IsSetter() const { | 551 bool IsSetter() const { |
| 551 return kind == RawFunction::kSetterFunction; | 552 return kind == RawFunction::kSetterFunction; |
| 552 } | 553 } |
| 554 const char* ToCString() const { |
| 555 if (field_ != NULL) { |
| 556 return "field"; |
| 557 } else if (IsConstructor()) { |
| 558 return "constructor"; |
| 559 } else if (IsFactory()) { |
| 560 return "factory"; |
| 561 } else if (IsGetter()) { |
| 562 return "getter"; |
| 563 } else if (IsSetter()) { |
| 564 return "setter"; |
| 565 } |
| 566 return "method"; |
| 567 } |
| 568 String* DictName() const { |
| 569 return (dict_name != NULL) ? dict_name : name; |
| 570 } |
| 553 bool has_abstract; | 571 bool has_abstract; |
| 554 bool has_external; | 572 bool has_external; |
| 555 bool has_final; | 573 bool has_final; |
| 556 bool has_const; | 574 bool has_const; |
| 557 bool has_static; | 575 bool has_static; |
| 558 bool has_var; | 576 bool has_var; |
| 559 bool has_factory; | 577 bool has_factory; |
| 560 bool has_operator; | 578 bool has_operator; |
| 561 intptr_t metadata_pos; | 579 intptr_t metadata_pos; |
| 562 Token::Kind operator_token; | 580 Token::Kind operator_token; |
| 563 const AbstractType* type; | 581 const AbstractType* type; |
| 564 intptr_t name_pos; | 582 intptr_t name_pos; |
| 565 intptr_t decl_begin_pos; | 583 intptr_t decl_begin_pos; |
| 566 String* name; | 584 String* name; |
| 567 // For constructors: NULL or name of redirected to constructor. | 585 // For constructors: NULL or name of redirected to constructor. |
| 568 String* redirect_name; | 586 String* redirect_name; |
| 587 // dict_name is the name used for the class namespace, if it |
| 588 // differs from 'name'. |
| 569 // For constructors: NULL for unnamed constructor, | 589 // For constructors: NULL for unnamed constructor, |
| 570 // identifier after classname for named constructors. | 590 // identifier after classname for named constructors. |
| 571 String* constructor_name; | 591 // For getters and setters: unmangled name. |
| 592 String* dict_name; |
| 572 ParamList params; | 593 ParamList params; |
| 573 RawFunction::Kind kind; | 594 RawFunction::Kind kind; |
| 595 // NULL for functions, field object for static or instance fields. |
| 596 Field* field_; |
| 574 }; | 597 }; |
| 575 | 598 |
| 576 | 599 |
| 577 class ClassDesc : public ValueObject { | 600 class ClassDesc : public ValueObject { |
| 578 public: | 601 public: |
| 579 ClassDesc(const Class& cls, | 602 ClassDesc(const Class& cls, |
| 580 const String& cls_name, | 603 const String& cls_name, |
| 581 bool is_interface, | 604 bool is_interface, |
| 582 intptr_t token_pos) | 605 intptr_t token_pos) |
| 583 : clazz_(cls), | 606 : clazz_(cls), |
| 584 class_name_(cls_name), | 607 class_name_(cls_name), |
| 585 token_pos_(token_pos), | 608 token_pos_(token_pos), |
| 586 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 609 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 587 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { | 610 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { |
| 588 } | 611 } |
| 589 | 612 |
| 590 // Parameter 'name' is the unmangled name, i.e. without the setter | |
| 591 // name mangling. | |
| 592 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { | |
| 593 // First check if a function or field of same name exists. | |
| 594 if ((kind != RawFunction::kSetterFunction) && FunctionExists(name)) { | |
| 595 return true; | |
| 596 } | |
| 597 // Now check whether there is a field and whether its implicit getter | |
| 598 // or setter collides with the name. | |
| 599 Field* field = LookupField(name); | |
| 600 if (field != NULL) { | |
| 601 if (kind == RawFunction::kSetterFunction) { | |
| 602 // It's ok to have an implicit getter, it does not collide with | |
| 603 // this setter function. | |
| 604 if (!field->is_final()) { | |
| 605 return true; | |
| 606 } | |
| 607 } else { | |
| 608 // The implicit getter of the field collides with the name. | |
| 609 return true; | |
| 610 } | |
| 611 } | |
| 612 | |
| 613 String& accessor_name = String::Handle(); | |
| 614 if (kind == RawFunction::kSetterFunction) { | |
| 615 // Check if a setter function of same name exists. | |
| 616 accessor_name = Field::SetterName(name); | |
| 617 if (FunctionExists(accessor_name)) { | |
| 618 return true; | |
| 619 } | |
| 620 } else { | |
| 621 // Check if a getter function of same name exists. | |
| 622 accessor_name = Field::GetterName(name); | |
| 623 if (FunctionExists(accessor_name)) { | |
| 624 return true; | |
| 625 } | |
| 626 } | |
| 627 return false; | |
| 628 } | |
| 629 | |
| 630 bool FieldNameExists(const String& name, bool check_setter) const { | |
| 631 // First check if a function or field of same name exists. | |
| 632 if (FunctionExists(name) || FieldExists(name)) { | |
| 633 return true; | |
| 634 } | |
| 635 // Now check if a getter/setter function of same name exists. | |
| 636 String& getter_name = String::Handle(Field::GetterName(name)); | |
| 637 if (FunctionExists(getter_name)) { | |
| 638 return true; | |
| 639 } | |
| 640 if (check_setter) { | |
| 641 String& setter_name = String::Handle(Field::SetterName(name)); | |
| 642 if (FunctionExists(setter_name)) { | |
| 643 return true; | |
| 644 } | |
| 645 } | |
| 646 return false; | |
| 647 } | |
| 648 | |
| 649 void AddFunction(const Function& function) { | 613 void AddFunction(const Function& function) { |
| 650 ASSERT(!FunctionExists(String::Handle(function.name()))); | |
| 651 functions_.Add(function); | 614 functions_.Add(function); |
| 652 } | 615 } |
| 653 | 616 |
| 654 const GrowableObjectArray& functions() const { | 617 const GrowableObjectArray& functions() const { |
| 655 return functions_; | 618 return functions_; |
| 656 } | 619 } |
| 657 | 620 |
| 658 void AddField(const Field& field) { | 621 void AddField(const Field& field) { |
| 659 ASSERT(!FieldExists(String::Handle(field.name()))); | |
| 660 fields_.Add(field); | 622 fields_.Add(field); |
| 661 } | 623 } |
| 662 | 624 |
| 663 const GrowableObjectArray& fields() const { | 625 const GrowableObjectArray& fields() const { |
| 664 return fields_; | 626 return fields_; |
| 665 } | 627 } |
| 666 | 628 |
| 667 const Class& clazz() const { | 629 const Class& clazz() const { |
| 668 return clazz_; | 630 return clazz_; |
| 669 } | 631 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 698 MemberDesc* LookupMember(const String& name) const { | 660 MemberDesc* LookupMember(const String& name) const { |
| 699 for (int i = 0; i < members_.length(); i++) { | 661 for (int i = 0; i < members_.length(); i++) { |
| 700 if (name.Equals(*members_[i].name)) { | 662 if (name.Equals(*members_[i].name)) { |
| 701 return &members_[i]; | 663 return &members_[i]; |
| 702 } | 664 } |
| 703 } | 665 } |
| 704 return NULL; | 666 return NULL; |
| 705 } | 667 } |
| 706 | 668 |
| 707 private: | 669 private: |
| 708 Field* LookupField(const String& name) const { | |
| 709 String& test_name = String::Handle(); | |
| 710 Field& field = Field::Handle(); | |
| 711 for (int i = 0; i < fields_.Length(); i++) { | |
| 712 field ^= fields_.At(i); | |
| 713 test_name = field.name(); | |
| 714 if (name.Equals(test_name)) { | |
| 715 return &field; | |
| 716 } | |
| 717 } | |
| 718 return NULL; | |
| 719 } | |
| 720 | |
| 721 bool FieldExists(const String& name) const { | |
| 722 return LookupField(name) != NULL; | |
| 723 } | |
| 724 | |
| 725 Function* LookupFunction(const String& name) const { | |
| 726 String& test_name = String::Handle(); | |
| 727 Function& func = Function::Handle(); | |
| 728 for (int i = 0; i < functions_.Length(); i++) { | |
| 729 func ^= functions_.At(i); | |
| 730 test_name = func.name(); | |
| 731 if (name.Equals(test_name)) { | |
| 732 return &func; | |
| 733 } | |
| 734 } | |
| 735 return NULL; | |
| 736 } | |
| 737 | |
| 738 bool FunctionExists(const String& name) const { | |
| 739 return LookupFunction(name) != NULL; | |
| 740 } | |
| 741 | |
| 742 const Class& clazz_; | 670 const Class& clazz_; |
| 743 const String& class_name_; | 671 const String& class_name_; |
| 744 intptr_t token_pos_; // Token index of "class" keyword. | 672 intptr_t token_pos_; // Token index of "class" keyword. |
| 745 GrowableObjectArray& functions_; | 673 GrowableObjectArray& functions_; |
| 746 GrowableObjectArray& fields_; | 674 GrowableObjectArray& fields_; |
| 747 GrowableArray<MemberDesc> members_; | 675 GrowableArray<MemberDesc> members_; |
| 748 }; | 676 }; |
| 749 | 677 |
| 750 | 678 |
| 751 struct TopLevel { | 679 struct TopLevel { |
| (...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3067 if ((method->operator_token == Token::kSUB) && | 2995 if ((method->operator_token == Token::kSUB) && |
| 3068 (method->params.num_fixed_parameters == 1)) { | 2996 (method->params.num_fixed_parameters == 1)) { |
| 3069 // Patch up name for unary operator - so it does not clash with the | 2997 // Patch up name for unary operator - so it does not clash with the |
| 3070 // name for binary operator -. | 2998 // name for binary operator -. |
| 3071 method->operator_token = Token::kNEGATE; | 2999 method->operator_token = Token::kNEGATE; |
| 3072 *method->name = Symbols::New(Token::Str(Token::kNEGATE)); | 3000 *method->name = Symbols::New(Token::Str(Token::kNEGATE)); |
| 3073 } | 3001 } |
| 3074 CheckOperatorArity(*method); | 3002 CheckOperatorArity(*method); |
| 3075 } | 3003 } |
| 3076 | 3004 |
| 3077 if (members->FunctionNameExists(*method->name, method->kind)) { | |
| 3078 ErrorMsg(method->name_pos, | |
| 3079 "field or method '%s' already defined", method->name->ToCString()); | |
| 3080 } | |
| 3081 | |
| 3082 // Mangle the name for getter and setter functions and check function | 3005 // Mangle the name for getter and setter functions and check function |
| 3083 // arity. | 3006 // arity. |
| 3084 if (method->IsGetter() || method->IsSetter()) { | 3007 if (method->IsGetter() || method->IsSetter()) { |
| 3085 int expected_num_parameters = 0; | 3008 int expected_num_parameters = 0; |
| 3086 if (method->IsGetter()) { | 3009 if (method->IsGetter()) { |
| 3087 expected_num_parameters = (method->has_static) ? 0 : 1; | 3010 expected_num_parameters = (method->has_static) ? 0 : 1; |
| 3011 method->dict_name = method->name; |
| 3088 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name)); | 3012 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name)); |
| 3089 } else { | 3013 } else { |
| 3090 ASSERT(method->IsSetter()); | 3014 ASSERT(method->IsSetter()); |
| 3091 expected_num_parameters = (method->has_static) ? 1 : 2; | 3015 expected_num_parameters = (method->has_static) ? 1 : 2; |
| 3016 method->dict_name = |
| 3017 &String::ZoneHandle(String::Concat(*method->name, Symbols::Equals())); |
| 3092 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); | 3018 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); |
| 3093 } | 3019 } |
| 3094 if ((method->params.num_fixed_parameters != expected_num_parameters) || | 3020 if ((method->params.num_fixed_parameters != expected_num_parameters) || |
| 3095 (method->params.num_optional_parameters != 0)) { | 3021 (method->params.num_optional_parameters != 0)) { |
| 3096 ErrorMsg(method->name_pos, "illegal %s parameters", | 3022 ErrorMsg(method->name_pos, "illegal %s parameters", |
| 3097 method->IsGetter() ? "getter" : "setter"); | 3023 method->IsGetter() ? "getter" : "setter"); |
| 3098 } | 3024 } |
| 3099 } | 3025 } |
| 3100 | 3026 |
| 3101 // Parse redirecting factory constructor. | 3027 // Parse redirecting factory constructor. |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3309 } | 3235 } |
| 3310 if (field->has_external) { | 3236 if (field->has_external) { |
| 3311 ErrorMsg("keyword 'external' not allowed in field declaration"); | 3237 ErrorMsg("keyword 'external' not allowed in field declaration"); |
| 3312 } | 3238 } |
| 3313 if (field->has_factory) { | 3239 if (field->has_factory) { |
| 3314 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 3240 ErrorMsg("keyword 'factory' not allowed in field declaration"); |
| 3315 } | 3241 } |
| 3316 if (!field->has_static && field->has_const) { | 3242 if (!field->has_static && field->has_const) { |
| 3317 ErrorMsg(field->name_pos, "instance field may not be 'const'"); | 3243 ErrorMsg(field->name_pos, "instance field may not be 'const'"); |
| 3318 } | 3244 } |
| 3319 if (members->FieldNameExists(*field->name, !field->has_final)) { | |
| 3320 ErrorMsg(field->name_pos, | |
| 3321 "field or method '%s' already defined", field->name->ToCString()); | |
| 3322 } | |
| 3323 Function& getter = Function::Handle(); | 3245 Function& getter = Function::Handle(); |
| 3324 Function& setter = Function::Handle(); | 3246 Function& setter = Function::Handle(); |
| 3325 Field& class_field = Field::Handle(); | 3247 Field& class_field = Field::ZoneHandle(); |
| 3326 Instance& init_value = Instance::Handle(); | 3248 Instance& init_value = Instance::Handle(); |
| 3327 while (true) { | 3249 while (true) { |
| 3328 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3250 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3329 bool has_simple_literal = false; | 3251 bool has_simple_literal = false; |
| 3330 if (has_initializer) { | 3252 if (has_initializer) { |
| 3331 ConsumeToken(); | 3253 ConsumeToken(); |
| 3332 init_value = Object::sentinel().raw(); | 3254 init_value = Object::sentinel().raw(); |
| 3333 // For static const fields and static final non-const fields, the | 3255 // For static const fields and static final non-const fields, the |
| 3334 // initialization expression will be parsed through the | 3256 // initialization expression will be parsed through the |
| 3335 // kImplicitStaticFinalGetter method invocation/compilation. | 3257 // kImplicitStaticFinalGetter method invocation/compilation. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3363 // Create the field object. | 3285 // Create the field object. |
| 3364 class_field = Field::New(*field->name, | 3286 class_field = Field::New(*field->name, |
| 3365 field->has_static, | 3287 field->has_static, |
| 3366 field->has_final, | 3288 field->has_final, |
| 3367 field->has_const, | 3289 field->has_const, |
| 3368 current_class(), | 3290 current_class(), |
| 3369 field->name_pos); | 3291 field->name_pos); |
| 3370 class_field.set_type(*field->type); | 3292 class_field.set_type(*field->type); |
| 3371 class_field.set_has_initializer(has_initializer); | 3293 class_field.set_has_initializer(has_initializer); |
| 3372 members->AddField(class_field); | 3294 members->AddField(class_field); |
| 3295 field->field_ = &class_field; |
| 3373 if (field->metadata_pos >= 0) { | 3296 if (field->metadata_pos >= 0) { |
| 3374 library_.AddFieldMetadata(class_field, field->metadata_pos); | 3297 library_.AddFieldMetadata(class_field, field->metadata_pos); |
| 3375 } | 3298 } |
| 3376 | 3299 |
| 3377 // For static final fields (this includes static const fields), set value to | 3300 // For static final fields (this includes static const fields), set value to |
| 3378 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. | 3301 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. |
| 3379 if (field->has_static && has_initializer) { | 3302 if (field->has_static && has_initializer) { |
| 3380 class_field.set_value(init_value); | 3303 class_field.set_value(init_value); |
| 3381 if (!has_simple_literal) { | 3304 if (!has_simple_literal) { |
| 3382 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); | 3305 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3456 member.params.has_optional_positional_parameters || | 3379 member.params.has_optional_positional_parameters || |
| 3457 member.params.has_optional_named_parameters || | 3380 member.params.has_optional_named_parameters || |
| 3458 (member.params.num_fixed_parameters != expected_num_parameters)) { | 3381 (member.params.num_fixed_parameters != expected_num_parameters)) { |
| 3459 // Subtract receiver when reporting number of expected arguments. | 3382 // Subtract receiver when reporting number of expected arguments. |
| 3460 ErrorMsg(member.name_pos, "operator %s expects %" Pd " argument(s)", | 3383 ErrorMsg(member.name_pos, "operator %s expects %" Pd " argument(s)", |
| 3461 member.name->ToCString(), (expected_num_parameters - 1)); | 3384 member.name->ToCString(), (expected_num_parameters - 1)); |
| 3462 } | 3385 } |
| 3463 } | 3386 } |
| 3464 | 3387 |
| 3465 | 3388 |
| 3389 void Parser::CheckMemberNameConflict(ClassDesc* members, |
| 3390 MemberDesc* member) { |
| 3391 const String& name = *member->DictName(); |
| 3392 if (name.Equals(members->class_name())) { |
| 3393 ErrorMsg(member->name_pos, |
| 3394 "%s '%s' conflicts with class name", |
| 3395 member->ToCString(), |
| 3396 name.ToCString()); |
| 3397 } |
| 3398 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { |
| 3399 ErrorMsg(member->name_pos, |
| 3400 "%s '%s' conflicts with type parameter", |
| 3401 member->ToCString(), |
| 3402 name.ToCString()); |
| 3403 } |
| 3404 for (int i = 0; i < members->members().length(); i++) { |
| 3405 MemberDesc* existing_member = &members->members()[i]; |
| 3406 if (name.Equals(*existing_member->DictName())) { |
| 3407 ErrorMsg(member->name_pos, |
| 3408 "%s '%s' conflicts with previously declared %s", |
| 3409 member->ToCString(), |
| 3410 name.ToCString(), |
| 3411 existing_member->ToCString()); |
| 3412 } |
| 3413 } |
| 3414 } |
| 3415 |
| 3416 |
| 3466 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 3417 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 3467 intptr_t metadata_pos) { | 3418 intptr_t metadata_pos) { |
| 3468 TRACE_PARSER("ParseClassMemberDefinition"); | 3419 TRACE_PARSER("ParseClassMemberDefinition"); |
| 3469 MemberDesc member; | 3420 MemberDesc member; |
| 3470 current_member_ = &member; | 3421 current_member_ = &member; |
| 3471 member.metadata_pos = metadata_pos; | 3422 member.metadata_pos = metadata_pos; |
| 3472 member.decl_begin_pos = TokenPos(); | 3423 member.decl_begin_pos = TokenPos(); |
| 3473 if ((CurrentToken() == Token::kEXTERNAL) && | 3424 if ((CurrentToken() == Token::kEXTERNAL) && |
| 3474 (LookaheadToken(1) != Token::kLPAREN)) { | 3425 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3475 ConsumeToken(); | 3426 ConsumeToken(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3572 result_type_class, | 3523 result_type_class, |
| 3573 TypeArguments::Handle(current_class().type_parameters()), | 3524 TypeArguments::Handle(current_class().type_parameters()), |
| 3574 member.name_pos)); | 3525 member.name_pos)); |
| 3575 | 3526 |
| 3576 // We must be dealing with a constructor or named constructor. | 3527 // We must be dealing with a constructor or named constructor. |
| 3577 member.kind = RawFunction::kConstructor; | 3528 member.kind = RawFunction::kConstructor; |
| 3578 *member.name = String::Concat(*member.name, Symbols::Dot()); | 3529 *member.name = String::Concat(*member.name, Symbols::Dot()); |
| 3579 if (CurrentToken() == Token::kPERIOD) { | 3530 if (CurrentToken() == Token::kPERIOD) { |
| 3580 // Named constructor. | 3531 // Named constructor. |
| 3581 ConsumeToken(); | 3532 ConsumeToken(); |
| 3582 member.constructor_name = ExpectIdentifier("identifier expected"); | 3533 member.dict_name = ExpectIdentifier("identifier expected"); |
| 3583 *member.name = String::Concat(*member.name, *member.constructor_name); | 3534 *member.name = String::Concat(*member.name, *member.dict_name); |
| 3584 } | 3535 } |
| 3585 // Ensure that names are symbols. | 3536 // Ensure that names are symbols. |
| 3586 *member.name = Symbols::New(*member.name); | 3537 *member.name = Symbols::New(*member.name); |
| 3587 | 3538 |
| 3588 if (CurrentToken() != Token::kLPAREN) { | 3539 if (CurrentToken() != Token::kLPAREN) { |
| 3589 ErrorMsg("left parenthesis expected"); | 3540 ErrorMsg("left parenthesis expected"); |
| 3590 } | 3541 } |
| 3591 } else if ((CurrentToken() == Token::kGET) && !member.has_var && | 3542 } else if ((CurrentToken() == Token::kGET) && !member.has_var && |
| 3592 (LookaheadToken(1) != Token::kLPAREN) && | 3543 (LookaheadToken(1) != Token::kLPAREN) && |
| 3593 (LookaheadToken(1) != Token::kASSIGN) && | 3544 (LookaheadToken(1) != Token::kASSIGN) && |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3636 ConsumeToken(); | 3587 ConsumeToken(); |
| 3637 } else if (IsIdentifier()) { | 3588 } else if (IsIdentifier()) { |
| 3638 member.name = CurrentLiteral(); | 3589 member.name = CurrentLiteral(); |
| 3639 member.name_pos = TokenPos(); | 3590 member.name_pos = TokenPos(); |
| 3640 ConsumeToken(); | 3591 ConsumeToken(); |
| 3641 } else { | 3592 } else { |
| 3642 ErrorMsg("identifier expected"); | 3593 ErrorMsg("identifier expected"); |
| 3643 } | 3594 } |
| 3644 | 3595 |
| 3645 ASSERT(member.name != NULL); | 3596 ASSERT(member.name != NULL); |
| 3646 if (member.kind != RawFunction::kConstructor) { | |
| 3647 if (member.name->Equals(members->class_name())) { | |
| 3648 ErrorMsg(member.name_pos, | |
| 3649 "class member must not have the same name as its class"); | |
| 3650 } | |
| 3651 } | |
| 3652 | |
| 3653 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { | 3597 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { |
| 3654 // Constructor or method. | 3598 // Constructor or method. |
| 3655 if (member.type == NULL) { | 3599 if (member.type == NULL) { |
| 3656 member.type = &Type::ZoneHandle(Type::DynamicType()); | 3600 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 3657 } | 3601 } |
| 3658 ASSERT(member.IsFactory() == member.has_factory); | 3602 ASSERT(member.IsFactory() == member.has_factory); |
| 3659 ParseMethodOrConstructor(members, &member); | 3603 ParseMethodOrConstructor(members, &member); |
| 3660 } else if (CurrentToken() == Token::kSEMICOLON || | 3604 } else if (CurrentToken() == Token::kSEMICOLON || |
| 3661 CurrentToken() == Token::kCOMMA || | 3605 CurrentToken() == Token::kCOMMA || |
| 3662 CurrentToken() == Token::kASSIGN) { | 3606 CurrentToken() == Token::kASSIGN) { |
| 3663 // Field definition. | 3607 // Field definition. |
| 3664 if (member.has_const) { | 3608 if (member.has_const) { |
| 3665 // const fields are implicitly final. | 3609 // const fields are implicitly final. |
| 3666 member.has_final = true; | 3610 member.has_final = true; |
| 3667 } | 3611 } |
| 3668 if (member.type == NULL) { | 3612 if (member.type == NULL) { |
| 3669 if (member.has_final) { | 3613 if (member.has_final) { |
| 3670 member.type = &Type::ZoneHandle(Type::DynamicType()); | 3614 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 3671 } else { | 3615 } else { |
| 3672 ErrorMsg("missing 'var', 'final', 'const' or type" | 3616 ErrorMsg("missing 'var', 'final', 'const' or type" |
| 3673 " in field declaration"); | 3617 " in field declaration"); |
| 3674 } | 3618 } |
| 3675 } | 3619 } |
| 3676 ParseFieldDefinition(members, &member); | 3620 ParseFieldDefinition(members, &member); |
| 3677 } else { | 3621 } else { |
| 3678 UnexpectedToken(); | 3622 UnexpectedToken(); |
| 3679 } | 3623 } |
| 3680 current_member_ = NULL; | 3624 current_member_ = NULL; |
| 3625 CheckMemberNameConflict(members, &member); |
| 3681 members->AddMember(member); | 3626 members->AddMember(member); |
| 3682 } | 3627 } |
| 3683 | 3628 |
| 3684 | 3629 |
| 3685 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 3630 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| 3686 intptr_t metadata_pos) { | 3631 intptr_t metadata_pos) { |
| 3687 TRACE_PARSER("ParseClassDeclaration"); | 3632 TRACE_PARSER("ParseClassDeclaration"); |
| 3688 bool is_patch = false; | 3633 bool is_patch = false; |
| 3689 bool is_abstract = false; | 3634 bool is_abstract = false; |
| 3690 if (is_patch_source() && | 3635 if (is_patch_source() && |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3938 &Type::ZoneHandle(Type::SmiType())); | 3883 &Type::ZoneHandle(Type::SmiType())); |
| 3939 | 3884 |
| 3940 AddFormalParamsToFunction(¶ms, ctor); | 3885 AddFormalParamsToFunction(¶ms, ctor); |
| 3941 // The body of the constructor cannot modify the type of the constructed | 3886 // The body of the constructor cannot modify the type of the constructed |
| 3942 // instance, which is passed in as the receiver. | 3887 // instance, which is passed in as the receiver. |
| 3943 ctor.set_result_type(*receiver_type); | 3888 ctor.set_result_type(*receiver_type); |
| 3944 cls.AddFunction(ctor); | 3889 cls.AddFunction(ctor); |
| 3945 } | 3890 } |
| 3946 | 3891 |
| 3947 | 3892 |
| 3948 // Check for cycles in constructor redirection. Also check whether a | 3893 // Check for cycles in constructor redirection. |
| 3949 // named constructor collides with the name of another class member. | |
| 3950 void Parser::CheckConstructors(ClassDesc* class_desc) { | 3894 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 3951 // Check for cycles in constructor redirection. | 3895 // Check for cycles in constructor redirection. |
| 3952 const GrowableArray<MemberDesc>& members = class_desc->members(); | 3896 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 3953 for (int i = 0; i < members.length(); i++) { | 3897 for (int i = 0; i < members.length(); i++) { |
| 3954 MemberDesc* member = &members[i]; | 3898 MemberDesc* member = &members[i]; |
| 3955 | 3899 if (member->redirect_name == NULL) { |
| 3956 if (member->constructor_name != NULL) { | 3900 continue; |
| 3957 // Check whether constructor name conflicts with a member name. | |
| 3958 if (class_desc->FunctionNameExists( | |
| 3959 *member->constructor_name, member->kind)) { | |
| 3960 ErrorMsg(member->name_pos, | |
| 3961 "Named constructor '%s' conflicts with method or field '%s'", | |
| 3962 member->name->ToCString(), | |
| 3963 member->constructor_name->ToCString()); | |
| 3964 } | |
| 3965 } | 3901 } |
| 3966 | |
| 3967 GrowableArray<MemberDesc*> ctors; | 3902 GrowableArray<MemberDesc*> ctors; |
| 3968 while ((member != NULL) && (member->redirect_name != NULL)) { | 3903 while ((member != NULL) && (member->redirect_name != NULL)) { |
| 3969 ASSERT(member->IsConstructor()); | 3904 ASSERT(member->IsConstructor()); |
| 3970 // Check whether we have already seen this member. | 3905 // Check whether we have already seen this member. |
| 3971 for (int i = 0; i < ctors.length(); i++) { | 3906 for (int i = 0; i < ctors.length(); i++) { |
| 3972 if (ctors[i] == member) { | 3907 if (ctors[i] == member) { |
| 3973 ErrorMsg(member->name_pos, | 3908 ErrorMsg(member->name_pos, |
| 3974 "cyclic reference in constructor redirection"); | 3909 "cyclic reference in constructor redirection"); |
| 3975 } | 3910 } |
| 3976 } | 3911 } |
| (...skipping 6642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10619 void Parser::SkipQualIdent() { | 10554 void Parser::SkipQualIdent() { |
| 10620 ASSERT(IsIdentifier()); | 10555 ASSERT(IsIdentifier()); |
| 10621 ConsumeToken(); | 10556 ConsumeToken(); |
| 10622 if (CurrentToken() == Token::kPERIOD) { | 10557 if (CurrentToken() == Token::kPERIOD) { |
| 10623 ConsumeToken(); // Consume the kPERIOD token. | 10558 ConsumeToken(); // Consume the kPERIOD token. |
| 10624 ExpectIdentifier("identifier expected after '.'"); | 10559 ExpectIdentifier("identifier expected after '.'"); |
| 10625 } | 10560 } |
| 10626 } | 10561 } |
| 10627 | 10562 |
| 10628 } // namespace dart | 10563 } // namespace dart |
| OLD | NEW |