| 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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 Clear(); | 440 Clear(); |
| 441 } | 441 } |
| 442 void Clear() { | 442 void Clear() { |
| 443 has_abstract = false; | 443 has_abstract = false; |
| 444 has_external = false; | 444 has_external = false; |
| 445 has_final = false; | 445 has_final = false; |
| 446 has_const = false; | 446 has_const = false; |
| 447 has_static = false; | 447 has_static = false; |
| 448 has_var = false; | 448 has_var = false; |
| 449 has_factory = false; | 449 has_factory = false; |
| 450 has_operator = false; |
| 450 type = NULL; | 451 type = NULL; |
| 451 name_pos = 0; | 452 name_pos = 0; |
| 452 name = NULL; | 453 name = NULL; |
| 453 redirect_name = NULL; | 454 redirect_name = NULL; |
| 454 params.Clear(); | 455 params.Clear(); |
| 455 kind = RawFunction::kRegularFunction; | 456 kind = RawFunction::kRegularFunction; |
| 456 } | 457 } |
| 457 bool IsConstructor() const { | 458 bool IsConstructor() const { |
| 458 return (kind == RawFunction::kConstructor) && !has_static; | 459 return (kind == RawFunction::kConstructor) && !has_static; |
| 459 } | 460 } |
| 460 bool IsFactory() const { | 461 bool IsFactory() const { |
| 461 return (kind == RawFunction::kConstructor) && has_static; | 462 return (kind == RawFunction::kConstructor) && has_static; |
| 462 } | 463 } |
| 463 bool IsFactoryOrConstructor() const { | 464 bool IsFactoryOrConstructor() const { |
| 464 return (kind == RawFunction::kConstructor); | 465 return (kind == RawFunction::kConstructor); |
| 465 } | 466 } |
| 466 bool IsGetter() const { | 467 bool IsGetter() const { |
| 467 return kind == RawFunction::kGetterFunction; | 468 return kind == RawFunction::kGetterFunction; |
| 468 } | 469 } |
| 469 bool IsSetter() const { | 470 bool IsSetter() const { |
| 470 return kind == RawFunction::kSetterFunction; | 471 return kind == RawFunction::kSetterFunction; |
| 471 } | 472 } |
| 472 bool has_abstract; | 473 bool has_abstract; |
| 473 bool has_external; | 474 bool has_external; |
| 474 bool has_final; | 475 bool has_final; |
| 475 bool has_const; | 476 bool has_const; |
| 476 bool has_static; | 477 bool has_static; |
| 477 bool has_var; | 478 bool has_var; |
| 478 bool has_factory; | 479 bool has_factory; |
| 480 bool has_operator; |
| 479 const AbstractType* type; | 481 const AbstractType* type; |
| 480 intptr_t name_pos; | 482 intptr_t name_pos; |
| 481 String* name; | 483 String* name; |
| 482 String* redirect_name; // For constructors: NULL or redirected constructor. | 484 String* redirect_name; // For constructors: NULL or redirected constructor. |
| 483 ParamList params; | 485 ParamList params; |
| 484 RawFunction::Kind kind; | 486 RawFunction::Kind kind; |
| 485 }; | 487 }; |
| 486 | 488 |
| 487 | 489 |
| 488 class ClassDesc : public ValueObject { | 490 class ClassDesc : public ValueObject { |
| (...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2288 } | 2290 } |
| 2289 if (method->has_abstract && members->is_interface()) { | 2291 if (method->has_abstract && members->is_interface()) { |
| 2290 ErrorMsg(method->name_pos, | 2292 ErrorMsg(method->name_pos, |
| 2291 "'abstract' method only allowed in class definition"); | 2293 "'abstract' method only allowed in class definition"); |
| 2292 } | 2294 } |
| 2293 if (method->has_external && members->is_interface()) { | 2295 if (method->has_external && members->is_interface()) { |
| 2294 ErrorMsg(method->name_pos, | 2296 ErrorMsg(method->name_pos, |
| 2295 "'external' method only allowed in class definition"); | 2297 "'external' method only allowed in class definition"); |
| 2296 } | 2298 } |
| 2297 | 2299 |
| 2298 if (members->FunctionNameExists(*method->name, method->kind)) { | |
| 2299 ErrorMsg(method->name_pos, | |
| 2300 "field or method '%s' already defined", method->name->ToCString()); | |
| 2301 } | |
| 2302 | |
| 2303 // Parse the formal parameters. | 2300 // Parse the formal parameters. |
| 2304 const bool are_implicitly_final = method->has_const; | 2301 const bool are_implicitly_final = method->has_const; |
| 2305 const bool allow_explicit_default_values = true; | 2302 const bool allow_explicit_default_values = true; |
| 2306 const intptr_t formal_param_pos = TokenPos(); | 2303 const intptr_t formal_param_pos = TokenPos(); |
| 2307 method->params.Clear(); | 2304 method->params.Clear(); |
| 2308 // Static functions do not have a receiver. | 2305 // Static functions do not have a receiver. |
| 2309 // The first parameter of a factory is the AbstractTypeArguments vector of | 2306 // The first parameter of a factory is the AbstractTypeArguments vector of |
| 2310 // the type of the instance to be allocated. | 2307 // the type of the instance to be allocated. |
| 2311 if (!method->has_static || method->IsConstructor()) { | 2308 if (!method->has_static || method->IsConstructor()) { |
| 2312 method->params.AddReceiver(ReceiverType(formal_param_pos)); | 2309 method->params.AddReceiver(ReceiverType(formal_param_pos)); |
| 2313 } else if (method->has_factory) { | 2310 } else if (method->has_factory) { |
| 2314 method->params.AddFinalParameter( | 2311 method->params.AddFinalParameter( |
| 2315 formal_param_pos, | 2312 formal_param_pos, |
| 2316 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), | 2313 &String::ZoneHandle(Symbols::TypeArgumentsParameter()), |
| 2317 &Type::ZoneHandle(Type::DynamicType())); | 2314 &Type::ZoneHandle(Type::DynamicType())); |
| 2318 } | 2315 } |
| 2319 // Constructors have an implicit parameter for the construction phase. | 2316 // Constructors have an implicit parameter for the construction phase. |
| 2320 if (method->IsConstructor()) { | 2317 if (method->IsConstructor()) { |
| 2321 method->params.AddFinalParameter( | 2318 method->params.AddFinalParameter( |
| 2322 TokenPos(), | 2319 TokenPos(), |
| 2323 &String::ZoneHandle(Symbols::PhaseParameter()), | 2320 &String::ZoneHandle(Symbols::PhaseParameter()), |
| 2324 &Type::ZoneHandle(Type::IntInterface())); | 2321 &Type::ZoneHandle(Type::IntInterface())); |
| 2325 } | 2322 } |
| 2326 if (are_implicitly_final) { | 2323 if (are_implicitly_final) { |
| 2327 method->params.SetImplicitlyFinal(); | 2324 method->params.SetImplicitlyFinal(); |
| 2328 } | 2325 } |
| 2329 ParseFormalParameterList(allow_explicit_default_values, &method->params); | 2326 ParseFormalParameterList(allow_explicit_default_values, &method->params); |
| 2327 |
| 2328 // Now that we know the parameter list, we can distinguish between the |
| 2329 // unary and binary operator -. |
| 2330 if (method->has_operator && |
| 2331 ((method->name->Equals(Token::Str(Token::kNEGATE))) || |
| 2332 method->name->Equals("-")) && |
| 2333 (method->params.num_fixed_parameters == 1)) { |
| 2334 // Patch up name for unary operator - so it does not clash with the |
| 2335 // name for binary operator -. |
| 2336 *method->name = Symbols::New("unary-"); |
| 2337 } |
| 2338 |
| 2339 if (members->FunctionNameExists(*method->name, method->kind)) { |
| 2340 ErrorMsg(method->name_pos, |
| 2341 "field or method '%s' already defined", method->name->ToCString()); |
| 2342 } |
| 2343 |
| 2344 // Mangle the name for getter and setter functions and check function |
| 2345 // arity. |
| 2330 if (method->IsGetter() || method->IsSetter()) { | 2346 if (method->IsGetter() || method->IsSetter()) { |
| 2331 int expected_num_parameters = 0; | 2347 int expected_num_parameters = 0; |
| 2332 if (method->IsGetter()) { | 2348 if (method->IsGetter()) { |
| 2333 expected_num_parameters = (method->has_static) ? 0 : 1; | 2349 expected_num_parameters = (method->has_static) ? 0 : 1; |
| 2334 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name)); | 2350 method->name = &String::ZoneHandle(Field::GetterSymbol(*method->name)); |
| 2335 } else { | 2351 } else { |
| 2336 ASSERT(method->IsSetter()); | 2352 ASSERT(method->IsSetter()); |
| 2337 expected_num_parameters = (method->has_static) ? 1 : 2; | 2353 expected_num_parameters = (method->has_static) ? 1 : 2; |
| 2338 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); | 2354 method->name = &String::ZoneHandle(Field::SetterSymbol(*method->name)); |
| 2339 } | 2355 } |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2623 break; | 2639 break; |
| 2624 } | 2640 } |
| 2625 ConsumeToken(); | 2641 ConsumeToken(); |
| 2626 field->name_pos = this->TokenPos(); | 2642 field->name_pos = this->TokenPos(); |
| 2627 field->name = ExpectIdentifier("field name expected"); | 2643 field->name = ExpectIdentifier("field name expected"); |
| 2628 } | 2644 } |
| 2629 ExpectSemicolon(); | 2645 ExpectSemicolon(); |
| 2630 } | 2646 } |
| 2631 | 2647 |
| 2632 | 2648 |
| 2633 void Parser::CheckOperatorArity( | 2649 void Parser::CheckOperatorArity(const MemberDesc& member, |
| 2634 const MemberDesc& member, Token::Kind operator_token) { | 2650 Token::Kind operator_token) { |
| 2635 intptr_t expected_num_parameters; // Includes receiver. | 2651 intptr_t expected_num_parameters; // Includes receiver. |
| 2636 if (operator_token == Token::kASSIGN_INDEX) { | 2652 if (operator_token == Token::kASSIGN_INDEX) { |
| 2637 expected_num_parameters = 3; | 2653 expected_num_parameters = 3; |
| 2654 } else if (operator_token == Token::kSUB) { |
| 2655 if (member.params.num_fixed_parameters == 1) { |
| 2656 // Unary operator minus (i.e. negate). |
| 2657 expected_num_parameters = 1; |
| 2658 } else { |
| 2659 expected_num_parameters = 2; |
| 2660 } |
| 2638 } else if ((operator_token == Token::kNEGATE) || | 2661 } else if ((operator_token == Token::kNEGATE) || |
| 2639 (operator_token == Token::kBIT_NOT)) { | 2662 (operator_token == Token::kBIT_NOT)) { |
| 2663 // TODO(hausner): Remove support for keyword 'negate'. |
| 2640 expected_num_parameters = 1; | 2664 expected_num_parameters = 1; |
| 2641 } else { | 2665 } else { |
| 2642 expected_num_parameters = 2; | 2666 expected_num_parameters = 2; |
| 2643 } | 2667 } |
| 2644 if ((member.params.num_optional_parameters > 0) || | 2668 if ((member.params.num_optional_parameters > 0) || |
| 2645 (member.params.has_named_optional_parameters) || | 2669 (member.params.has_named_optional_parameters) || |
| 2646 (member.params.num_fixed_parameters != expected_num_parameters)) { | 2670 (member.params.num_fixed_parameters != expected_num_parameters)) { |
| 2647 // Subtract receiver when reporting number of expected arguments. | 2671 // Subtract receiver when reporting number of expected arguments. |
| 2648 ErrorMsg(member.name_pos, "operator %s expects %d argument(s)", | 2672 ErrorMsg(member.name_pos, "operator %s expects %d argument(s)", |
| 2649 member.name->ToCString(), (expected_num_parameters - 1)); | 2673 member.name->ToCString(), (expected_num_parameters - 1)); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2817 (LookaheadToken(1) != Token::kCOMMA) && | 2841 (LookaheadToken(1) != Token::kCOMMA) && |
| 2818 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2842 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 2819 ConsumeToken(); | 2843 ConsumeToken(); |
| 2820 if (!Token::CanBeOverloaded(CurrentToken())) { | 2844 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 2821 ErrorMsg("invalid operator overloading"); | 2845 ErrorMsg("invalid operator overloading"); |
| 2822 } | 2846 } |
| 2823 if (member.has_static) { | 2847 if (member.has_static) { |
| 2824 ErrorMsg("operator overloading functions cannot be static"); | 2848 ErrorMsg("operator overloading functions cannot be static"); |
| 2825 } | 2849 } |
| 2826 operator_token = CurrentToken(); | 2850 operator_token = CurrentToken(); |
| 2851 member.has_operator = true; |
| 2827 member.kind = RawFunction::kRegularFunction; | 2852 member.kind = RawFunction::kRegularFunction; |
| 2828 member.name_pos = this->TokenPos(); | 2853 member.name_pos = this->TokenPos(); |
| 2829 member.name = | 2854 member.name = |
| 2830 &String::ZoneHandle(Symbols::New(Token::Str(operator_token))); | 2855 &String::ZoneHandle(Symbols::New(Token::Str(operator_token))); |
| 2831 ConsumeToken(); | 2856 ConsumeToken(); |
| 2832 } else if (IsIdentifier()) { | 2857 } else if (IsIdentifier()) { |
| 2833 member.name = CurrentLiteral(); | 2858 member.name = CurrentLiteral(); |
| 2834 member.name_pos = TokenPos(); | 2859 member.name_pos = TokenPos(); |
| 2835 ConsumeToken(); | 2860 ConsumeToken(); |
| 2836 } else { | 2861 } else { |
| 2837 ErrorMsg("identifier expected"); | 2862 ErrorMsg("identifier expected"); |
| 2838 } | 2863 } |
| 2839 | 2864 |
| 2840 ASSERT(member.name != NULL); | 2865 ASSERT(member.name != NULL); |
| 2841 if (CurrentToken() == Token::kLPAREN) { | 2866 if (CurrentToken() == Token::kLPAREN) { |
| 2842 if (members->is_interface() && member.has_static) { | 2867 if (members->is_interface() && member.has_static) { |
| 2843 if (member.has_factory) { | 2868 if (member.has_factory) { |
| 2844 ErrorMsg("factory constructors are not allowed in interfaces"); | 2869 ErrorMsg("factory constructors are not allowed in interfaces"); |
| 2845 } else { | 2870 } else { |
| 2846 ErrorMsg("static methods are not allowed in interfaces"); | 2871 ErrorMsg("static methods are not allowed in interfaces"); |
| 2847 } | 2872 } |
| 2848 } | 2873 } |
| 2849 // Constructor or method. | 2874 // Constructor or method. |
| 2850 if (member.type == NULL) { | 2875 if (member.type == NULL) { |
| 2851 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2876 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2852 } | 2877 } |
| 2853 ParseMethodOrConstructor(members, &member); | 2878 ParseMethodOrConstructor(members, &member); |
| 2854 if (operator_token != Token::kILLEGAL) { | 2879 if (member.has_operator) { |
| 2855 CheckOperatorArity(member, operator_token); | 2880 CheckOperatorArity(member, operator_token); |
| 2856 } | 2881 } |
| 2857 } else if (CurrentToken() == Token::kSEMICOLON || | 2882 } else if (CurrentToken() == Token::kSEMICOLON || |
| 2858 CurrentToken() == Token::kCOMMA || | 2883 CurrentToken() == Token::kCOMMA || |
| 2859 CurrentToken() == Token::kASSIGN) { | 2884 CurrentToken() == Token::kASSIGN) { |
| 2860 // Field definition. | 2885 // Field definition. |
| 2861 if (member.has_const) { | 2886 if (member.has_const) { |
| 2862 // const fields are implicitly final. | 2887 // const fields are implicitly final. |
| 2863 member.has_final = true; | 2888 member.has_final = true; |
| 2864 } | 2889 } |
| (...skipping 6147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9012 void Parser::SkipQualIdent() { | 9037 void Parser::SkipQualIdent() { |
| 9013 ASSERT(IsIdentifier()); | 9038 ASSERT(IsIdentifier()); |
| 9014 ConsumeToken(); | 9039 ConsumeToken(); |
| 9015 if (CurrentToken() == Token::kPERIOD) { | 9040 if (CurrentToken() == Token::kPERIOD) { |
| 9016 ConsumeToken(); // Consume the kPERIOD token. | 9041 ConsumeToken(); // Consume the kPERIOD token. |
| 9017 ExpectIdentifier("identifier expected after '.'"); | 9042 ExpectIdentifier("identifier expected after '.'"); |
| 9018 } | 9043 } |
| 9019 } | 9044 } |
| 9020 | 9045 |
| 9021 } // namespace dart | 9046 } // namespace dart |
| OLD | NEW |