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