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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 | 490 |
491 class ClassDesc : public ValueObject { | 491 class ClassDesc : public ValueObject { |
492 public: | 492 public: |
493 ClassDesc(const Class& cls, | 493 ClassDesc(const Class& cls, |
494 const String& cls_name, | 494 const String& cls_name, |
495 bool is_interface, | 495 bool is_interface, |
496 intptr_t token_pos) | 496 intptr_t token_pos) |
497 : clazz_(cls), | 497 : clazz_(cls), |
498 class_name_(cls_name), | 498 class_name_(cls_name), |
499 is_interface_(is_interface), | 499 is_interface_(is_interface), |
| 500 is_abstract_(false), |
500 token_pos_(token_pos), | 501 token_pos_(token_pos), |
501 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 502 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
502 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { | 503 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { |
503 } | 504 } |
504 | 505 |
505 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { | 506 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { |
506 // First check if a function or field of same name exists. | 507 // First check if a function or field of same name exists. |
507 if (NameExists<Function>(functions_, name) || | 508 if (NameExists<Function>(functions_, name) || |
508 NameExists<Field>(fields_, name)) { | 509 NameExists<Field>(fields_, name)) { |
509 return true; | 510 return true; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 } | 566 } |
566 | 567 |
567 const String& class_name() const { | 568 const String& class_name() const { |
568 return class_name_; | 569 return class_name_; |
569 } | 570 } |
570 | 571 |
571 bool is_interface() const { | 572 bool is_interface() const { |
572 return is_interface_; | 573 return is_interface_; |
573 } | 574 } |
574 | 575 |
| 576 void set_is_abstract() { |
| 577 is_abstract_ = true; |
| 578 } |
| 579 |
| 580 bool is_abstract() const { |
| 581 return is_abstract_; |
| 582 } |
| 583 |
575 bool has_constructor() const { | 584 bool has_constructor() const { |
576 Function& func = Function::Handle(); | 585 Function& func = Function::Handle(); |
577 for (int i = 0; i < functions_.Length(); i++) { | 586 for (int i = 0; i < functions_.Length(); i++) { |
578 func ^= functions_.At(i); | 587 func ^= functions_.At(i); |
579 if (func.kind() == RawFunction::kConstructor) { | 588 if (func.kind() == RawFunction::kConstructor) { |
580 return true; | 589 return true; |
581 } | 590 } |
582 } | 591 } |
583 return false; | 592 return false; |
584 } | 593 } |
(...skipping 30 matching lines...) Expand all Loading... |
615 if (name.Equals(test_name)) { | 624 if (name.Equals(test_name)) { |
616 return true; | 625 return true; |
617 } | 626 } |
618 } | 627 } |
619 return false; | 628 return false; |
620 } | 629 } |
621 | 630 |
622 const Class& clazz_; | 631 const Class& clazz_; |
623 const String& class_name_; | 632 const String& class_name_; |
624 const bool is_interface_; | 633 const bool is_interface_; |
| 634 bool is_abstract_; |
625 intptr_t token_pos_; // Token index of "class" keyword. | 635 intptr_t token_pos_; // Token index of "class" keyword. |
626 GrowableObjectArray& functions_; | 636 GrowableObjectArray& functions_; |
627 GrowableObjectArray& fields_; | 637 GrowableObjectArray& fields_; |
628 GrowableArray<MemberDesc> members_; | 638 GrowableArray<MemberDesc> members_; |
629 }; | 639 }; |
630 | 640 |
631 | 641 |
632 struct TopLevel { | 642 struct TopLevel { |
633 TopLevel() : | 643 TopLevel() : |
634 fields(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 644 fields(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
(...skipping 1833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2468 } else if (method->IsConstructor() && method->has_const) { | 2478 } else if (method->IsConstructor() && method->has_const) { |
2469 ErrorMsg(method->name_pos, | 2479 ErrorMsg(method->name_pos, |
2470 "const constructor '%s' may not have a function body", | 2480 "const constructor '%s' may not have a function body", |
2471 method->name->ToCString()); | 2481 method->name->ToCString()); |
2472 } | 2482 } |
2473 if (method->redirect_name != NULL) { | 2483 if (method->redirect_name != NULL) { |
2474 ErrorMsg(method->name_pos, | 2484 ErrorMsg(method->name_pos, |
2475 "Constructor with redirection may not have a function body"); | 2485 "Constructor with redirection may not have a function body"); |
2476 } | 2486 } |
2477 ParseNativeDeclaration(); | 2487 ParseNativeDeclaration(); |
2478 } else if (CurrentToken() == Token::kSEMICOLON) { | 2488 } else { |
2479 if (members->is_interface() || | 2489 // We haven't found a method body. Issue error if one is required. |
2480 method->has_abstract || | 2490 const bool must_have_body = |
2481 method->has_external || | 2491 !members->is_interface() && |
2482 (method->redirect_name != NULL) || | 2492 method->has_static && !method->has_external; |
2483 method->IsConstructor()) { | 2493 if (must_have_body) { |
2484 ConsumeToken(); | |
2485 } else { | |
2486 ErrorMsg(method->name_pos, | 2494 ErrorMsg(method->name_pos, |
2487 "function body expected for method '%s'", | 2495 "function body expected for method '%s'", |
2488 method->name->ToCString()); | 2496 method->name->ToCString()); |
2489 } | 2497 } |
2490 } else { | 2498 |
2491 if (members->is_interface() || | 2499 if (CurrentToken() == Token::kSEMICOLON) { |
2492 method->has_abstract || | 2500 ConsumeToken(); |
2493 method->has_external || | 2501 if (!members->is_interface() && |
2494 (method->redirect_name != NULL) || | 2502 !method->has_static && |
2495 (method->IsConstructor() && method->has_const)) { | 2503 !method->has_external && |
2496 ExpectSemicolon(); | 2504 !method->IsConstructor()) { |
| 2505 // Methods, getters and setters without a body are |
| 2506 // implicitly abstract. |
| 2507 method->has_abstract = true; |
| 2508 } |
2497 } else { | 2509 } else { |
2498 ErrorMsg(method->name_pos, | 2510 // Signature is not followed by semicolon or body. Issue an |
2499 "function body expected for method '%s'", | 2511 // appropriate error. |
2500 method->name->ToCString()); | 2512 const bool must_have_semicolon = |
| 2513 members->is_interface() || |
| 2514 (method->redirect_name != NULL) || |
| 2515 (method->IsConstructor() && method->has_const) || |
| 2516 method->has_external; |
| 2517 if (must_have_semicolon) { |
| 2518 ExpectSemicolon(); |
| 2519 } else { |
| 2520 ErrorMsg(method->name_pos, |
| 2521 "function body or semicolon expected for method '%s'", |
| 2522 method->name->ToCString()); |
| 2523 } |
2501 } | 2524 } |
2502 } | 2525 } |
2503 | 2526 |
2504 RawFunction::Kind function_kind; | 2527 RawFunction::Kind function_kind; |
2505 if (method->IsFactoryOrConstructor()) { | 2528 if (method->IsFactoryOrConstructor()) { |
2506 function_kind = RawFunction::kConstructor; | 2529 function_kind = RawFunction::kConstructor; |
2507 } else if (method->IsGetter()) { | 2530 } else if (method->IsGetter()) { |
2508 function_kind = RawFunction::kGetterFunction; | 2531 function_kind = RawFunction::kGetterFunction; |
2509 } else if (method->IsSetter()) { | 2532 } else if (method->IsSetter()) { |
2510 function_kind = RawFunction::kSetterFunction; | 2533 function_kind = RawFunction::kSetterFunction; |
2511 } else { | 2534 } else { |
2512 function_kind = RawFunction::kRegularFunction; | 2535 function_kind = RawFunction::kRegularFunction; |
2513 } | 2536 } |
2514 Function& func = Function::Handle( | 2537 Function& func = Function::Handle( |
2515 Function::New(*method->name, | 2538 Function::New(*method->name, |
2516 function_kind, | 2539 function_kind, |
2517 method->has_static, | 2540 method->has_static, |
2518 method->has_const, | 2541 method->has_const, |
2519 method->has_abstract, | 2542 method->has_abstract, |
2520 method->has_external, | 2543 method->has_external, |
2521 current_class(), | 2544 current_class(), |
2522 method_pos)); | 2545 method_pos)); |
2523 func.set_result_type(*method->type); | 2546 func.set_result_type(*method->type); |
2524 func.set_end_token_pos(method_end_pos); | 2547 func.set_end_token_pos(method_end_pos); |
2525 | 2548 |
2526 // No need to resolve parameter types yet, or add parameters to local scope. | 2549 // No need to resolve parameter types yet, or add parameters to local scope. |
2527 ASSERT(is_top_level_); | 2550 ASSERT(is_top_level_); |
2528 AddFormalParamsToFunction(&method->params, func); | 2551 AddFormalParamsToFunction(&method->params, func); |
2529 members->AddFunction(func); | 2552 members->AddFunction(func); |
| 2553 if (method->has_abstract) { |
| 2554 members->set_is_abstract(); |
| 2555 } |
2530 } | 2556 } |
2531 | 2557 |
2532 | 2558 |
2533 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 2559 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
2534 TRACE_PARSER("ParseFieldDefinition"); | 2560 TRACE_PARSER("ParseFieldDefinition"); |
2535 // The parser has read the first field name and is now at the token | 2561 // The parser has read the first field name and is now at the token |
2536 // after the field name. | 2562 // after the field name. |
2537 ASSERT(CurrentToken() == Token::kSEMICOLON || | 2563 ASSERT(CurrentToken() == Token::kSEMICOLON || |
2538 CurrentToken() == Token::kCOMMA || | 2564 CurrentToken() == Token::kCOMMA || |
2539 CurrentToken() == Token::kASSIGN); | 2565 CurrentToken() == Token::kASSIGN); |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2923 } else { | 2949 } else { |
2924 UnexpectedToken(); | 2950 UnexpectedToken(); |
2925 } | 2951 } |
2926 current_member_ = NULL; | 2952 current_member_ = NULL; |
2927 members->AddMember(member); | 2953 members->AddMember(member); |
2928 } | 2954 } |
2929 | 2955 |
2930 | 2956 |
2931 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { | 2957 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { |
2932 TRACE_PARSER("ParseClassDefinition"); | 2958 TRACE_PARSER("ParseClassDefinition"); |
2933 const intptr_t class_pos = TokenPos(); | |
2934 bool is_patch = false; | 2959 bool is_patch = false; |
| 2960 bool is_abstract = false; |
2935 if (is_patch_source() && | 2961 if (is_patch_source() && |
2936 (CurrentToken() == Token::kIDENT) && | 2962 (CurrentToken() == Token::kIDENT) && |
2937 CurrentLiteral()->Equals("patch")) { | 2963 CurrentLiteral()->Equals("patch")) { |
2938 ConsumeToken(); | 2964 ConsumeToken(); |
2939 is_patch = true; | 2965 is_patch = true; |
| 2966 } else if (CurrentToken() == Token::kABSTRACT) { |
| 2967 is_abstract = true; |
| 2968 ConsumeToken(); |
2940 } | 2969 } |
| 2970 const intptr_t class_pos = TokenPos(); |
2941 ExpectToken(Token::kCLASS); | 2971 ExpectToken(Token::kCLASS); |
2942 const intptr_t classname_pos = TokenPos(); | 2972 const intptr_t classname_pos = TokenPos(); |
2943 String& class_name = *ExpectClassIdentifier("class name expected"); | 2973 String& class_name = *ExpectClassIdentifier("class name expected"); |
2944 if (FLAG_trace_parser) { | 2974 if (FLAG_trace_parser) { |
2945 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 2975 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
2946 } | 2976 } |
2947 Class& cls = Class::Handle(); | 2977 Class& cls = Class::Handle(); |
2948 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 2978 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
2949 if (obj.IsNull()) { | 2979 if (obj.IsNull()) { |
2950 if (is_patch) { | 2980 if (is_patch) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3018 AddInterfaces(interfaces_pos, cls, interfaces); | 3048 AddInterfaces(interfaces_pos, cls, interfaces); |
3019 } | 3049 } |
3020 | 3050 |
3021 ExpectToken(Token::kLBRACE); | 3051 ExpectToken(Token::kLBRACE); |
3022 ClassDesc members(cls, class_name, false, class_pos); | 3052 ClassDesc members(cls, class_name, false, class_pos); |
3023 while (CurrentToken() != Token::kRBRACE) { | 3053 while (CurrentToken() != Token::kRBRACE) { |
3024 ParseClassMemberDefinition(&members); | 3054 ParseClassMemberDefinition(&members); |
3025 } | 3055 } |
3026 ExpectToken(Token::kRBRACE); | 3056 ExpectToken(Token::kRBRACE); |
3027 | 3057 |
| 3058 if (is_abstract || members.is_abstract()) { |
| 3059 cls.set_is_abstract(); |
| 3060 } |
| 3061 |
3028 // Add an implicit constructor if no explicit constructor is present. No | 3062 // Add an implicit constructor if no explicit constructor is present. No |
3029 // implicit constructors are needed for patch classes. | 3063 // implicit constructors are needed for patch classes. |
3030 if (!members.has_constructor() && !is_patch) { | 3064 if (!members.has_constructor() && !is_patch) { |
3031 AddImplicitConstructor(&members); | 3065 AddImplicitConstructor(&members); |
3032 } | 3066 } |
3033 CheckConstructorCycles(&members); | 3067 CheckConstructorCycles(&members); |
3034 | 3068 |
3035 Array& array = Array::Handle(); | 3069 Array& array = Array::Handle(); |
3036 array = Array::MakeArray(members.fields()); | 3070 array = Array::MakeArray(members.fields()); |
3037 cls.SetFields(array); | 3071 cls.SetFields(array); |
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4066 set_current_class(Class::Handle()); // No current class. | 4100 set_current_class(Class::Handle()); // No current class. |
4067 if (CurrentToken() == Token::kCLASS) { | 4101 if (CurrentToken() == Token::kCLASS) { |
4068 ParseClassDefinition(pending_classes); | 4102 ParseClassDefinition(pending_classes); |
4069 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4103 } else if ((CurrentToken() == Token::kTYPEDEF) && |
4070 (LookaheadToken(1) != Token::kLPAREN)) { | 4104 (LookaheadToken(1) != Token::kLPAREN)) { |
4071 ParseFunctionTypeAlias(pending_classes); | 4105 ParseFunctionTypeAlias(pending_classes); |
4072 } else if (CurrentToken() == Token::kINTERFACE) { | 4106 } else if (CurrentToken() == Token::kINTERFACE) { |
4073 ParseInterfaceDefinition(pending_classes); | 4107 ParseInterfaceDefinition(pending_classes); |
4074 } else if ((CurrentToken() == Token::kABSTRACT) && | 4108 } else if ((CurrentToken() == Token::kABSTRACT) && |
4075 (LookaheadToken(1) == Token::kCLASS)) { | 4109 (LookaheadToken(1) == Token::kCLASS)) { |
4076 ConsumeToken(); // Consume and ignore 'abstract'. | |
4077 ParseClassDefinition(pending_classes); | 4110 ParseClassDefinition(pending_classes); |
4078 } else if (is_patch_source() && IsLiteral("patch") && | 4111 } else if (is_patch_source() && IsLiteral("patch") && |
4079 (LookaheadToken(1) == Token::kCLASS)) { | 4112 (LookaheadToken(1) == Token::kCLASS)) { |
4080 ParseClassDefinition(pending_classes); | 4113 ParseClassDefinition(pending_classes); |
4081 } else { | 4114 } else { |
4082 set_current_class(toplevel_class); | 4115 set_current_class(toplevel_class); |
4083 if (IsVariableDeclaration()) { | 4116 if (IsVariableDeclaration()) { |
4084 ParseTopLevelVariable(&top_level); | 4117 ParseTopLevelVariable(&top_level); |
4085 } else if (IsFunctionDeclaration()) { | 4118 } else if (IsFunctionDeclaration()) { |
4086 ParseTopLevelFunction(&top_level); | 4119 ParseTopLevelFunction(&top_level); |
(...skipping 4362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8449 // In that case, we throw a dynamic type error instead of calling the | 8482 // In that case, we throw a dynamic type error instead of calling the |
8450 // constructor. | 8483 // constructor. |
8451 if (type.IsTypeParameter()) { | 8484 if (type.IsTypeParameter()) { |
8452 ErrorMsg(type_pos, | 8485 ErrorMsg(type_pos, |
8453 "type parameter '%s' cannot be instantiated", | 8486 "type parameter '%s' cannot be instantiated", |
8454 String::Handle(type.UserVisibleName()).ToCString()); | 8487 String::Handle(type.UserVisibleName()).ToCString()); |
8455 } | 8488 } |
8456 if (type.IsDynamicType()) { | 8489 if (type.IsDynamicType()) { |
8457 ErrorMsg(type_pos, "Dynamic cannot be instantiated"); | 8490 ErrorMsg(type_pos, "Dynamic cannot be instantiated"); |
8458 } | 8491 } |
8459 Class& type_class = Class::Handle(type.type_class()); | 8492 const Class& type_class = Class::Handle(type.type_class()); |
8460 String& type_class_name = String::Handle(type_class.Name()); | 8493 const String& type_class_name = String::Handle(type_class.Name()); |
8461 AbstractTypeArguments& type_arguments = | 8494 AbstractTypeArguments& type_arguments = |
8462 AbstractTypeArguments::ZoneHandle(type.arguments()); | 8495 AbstractTypeArguments::ZoneHandle(type.arguments()); |
8463 | 8496 |
8464 // The constructor class and its name are those of the parsed type, unless the | 8497 // The constructor class and its name are those of the parsed type, unless the |
8465 // parsed type is an interface and a default factory class is specified, in | 8498 // parsed type is an interface and a default factory class is specified, in |
8466 // which case constructor_class and constructor_class_name are modified below. | 8499 // which case constructor_class and constructor_class_name are modified below. |
8467 Class& constructor_class = Class::ZoneHandle(type_class.raw()); | 8500 Class& constructor_class = Class::ZoneHandle(type_class.raw()); |
8468 String& constructor_class_name = String::Handle(type_class_name.raw()); | 8501 String& constructor_class_name = String::Handle(type_class_name.raw()); |
8469 | 8502 |
8470 // The grammar allows for an optional ('.' identifier)? after the type, which | 8503 // The grammar allows for an optional ('.' identifier)? after the type, which |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8555 arguments_length -= 1; | 8588 arguments_length -= 1; |
8556 } | 8589 } |
8557 if (constructor.IsNull()) { | 8590 if (constructor.IsNull()) { |
8558 const String& external_constructor_name = | 8591 const String& external_constructor_name = |
8559 (named_constructor ? constructor_name : constructor_class_name); | 8592 (named_constructor ? constructor_name : constructor_class_name); |
8560 ErrorMsg(type_pos, | 8593 ErrorMsg(type_pos, |
8561 "class '%s' has no constructor or factory named '%s'", | 8594 "class '%s' has no constructor or factory named '%s'", |
8562 String::Handle(constructor_class.Name()).ToCString(), | 8595 String::Handle(constructor_class.Name()).ToCString(), |
8563 external_constructor_name.ToCString()); | 8596 external_constructor_name.ToCString()); |
8564 } | 8597 } |
| 8598 |
| 8599 // It is ok to call a factory method of an abstract class, but it is |
| 8600 // an error to instantiate an abstract class. |
| 8601 if (constructor_class.is_abstract() && !constructor.IsFactory()) { |
| 8602 ErrorMsg(type_pos, "Cannot instantiate abstract class %s", |
| 8603 constructor_class_name.ToCString()); |
| 8604 } |
| 8605 |
8565 String& error_message = String::Handle(); | 8606 String& error_message = String::Handle(); |
8566 if (!constructor.AreValidArguments(arguments_length, | 8607 if (!constructor.AreValidArguments(arguments_length, |
8567 arguments->names(), | 8608 arguments->names(), |
8568 &error_message)) { | 8609 &error_message)) { |
8569 const String& external_constructor_name = | 8610 const String& external_constructor_name = |
8570 (named_constructor ? constructor_name : constructor_class_name); | 8611 (named_constructor ? constructor_name : constructor_class_name); |
8571 ErrorMsg(call_pos, | 8612 ErrorMsg(call_pos, |
8572 "invalid arguments passed to constructor '%s' for class '%s': %s", | 8613 "invalid arguments passed to constructor '%s' for class '%s': %s", |
8573 external_constructor_name.ToCString(), | 8614 external_constructor_name.ToCString(), |
8574 String::Handle(constructor_class.Name()).ToCString(), | 8615 String::Handle(constructor_class.Name()).ToCString(), |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9240 void Parser::SkipQualIdent() { | 9281 void Parser::SkipQualIdent() { |
9241 ASSERT(IsIdentifier()); | 9282 ASSERT(IsIdentifier()); |
9242 ConsumeToken(); | 9283 ConsumeToken(); |
9243 if (CurrentToken() == Token::kPERIOD) { | 9284 if (CurrentToken() == Token::kPERIOD) { |
9244 ConsumeToken(); // Consume the kPERIOD token. | 9285 ConsumeToken(); // Consume the kPERIOD token. |
9245 ExpectIdentifier("identifier expected after '.'"); | 9286 ExpectIdentifier("identifier expected after '.'"); |
9246 } | 9287 } |
9247 } | 9288 } |
9248 | 9289 |
9249 } // namespace dart | 9290 } // namespace dart |
OLD | NEW |