Chromium Code Reviews| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 666 struct ParamDesc { | 666 struct ParamDesc { |
| 667 ParamDesc() | 667 ParamDesc() |
| 668 : type(NULL), | 668 : type(NULL), |
| 669 name_pos(TokenPosition::kNoSource), | 669 name_pos(TokenPosition::kNoSource), |
| 670 name(NULL), | 670 name(NULL), |
| 671 default_value(NULL), | 671 default_value(NULL), |
| 672 metadata(NULL), | 672 metadata(NULL), |
| 673 var(NULL), | 673 var(NULL), |
| 674 is_final(false), | 674 is_final(false), |
| 675 is_field_initializer(false), | 675 is_field_initializer(false), |
| 676 has_explicit_type(false) {} | 676 has_explicit_type(false), |
| 677 is_covariant(false) {} | |
| 677 const AbstractType* type; | 678 const AbstractType* type; |
| 678 TokenPosition name_pos; | 679 TokenPosition name_pos; |
| 679 const String* name; | 680 const String* name; |
| 680 const Instance* default_value; // NULL if not an optional parameter. | 681 const Instance* default_value; // NULL if not an optional parameter. |
| 681 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 682 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
| 682 LocalVariable* var; // Scope variable allocated for this parameter. | 683 LocalVariable* var; // Scope variable allocated for this parameter. |
| 683 bool is_final; | 684 bool is_final; |
| 684 bool is_field_initializer; | 685 bool is_field_initializer; |
| 685 bool has_explicit_type; | 686 bool has_explicit_type; |
| 687 bool is_covariant; | |
| 686 }; | 688 }; |
| 687 | 689 |
| 688 | 690 |
| 689 struct ParamList { | 691 struct ParamList { |
| 690 ParamList() { Clear(); } | 692 ParamList() { Clear(); } |
| 691 | 693 |
| 692 void Clear() { | 694 void Clear() { |
| 693 num_fixed_parameters = 0; | 695 num_fixed_parameters = 0; |
| 694 num_optional_parameters = 0; | 696 num_optional_parameters = 0; |
| 695 has_optional_positional_parameters = false; | 697 has_optional_positional_parameters = false; |
| 696 has_optional_named_parameters = false; | 698 has_optional_named_parameters = false; |
| 697 has_explicit_default_values = false; | 699 has_explicit_default_values = false; |
| 698 has_field_initializer = false; | 700 has_field_initializer = false; |
| 701 has_covariant = false; | |
| 699 implicitly_final = false; | 702 implicitly_final = false; |
| 700 skipped = false; | 703 skipped = false; |
| 701 this->parameters = new ZoneGrowableArray<ParamDesc>(); | 704 this->parameters = new ZoneGrowableArray<ParamDesc>(); |
| 702 } | 705 } |
| 703 | 706 |
| 704 void AddFinalParameter(TokenPosition name_pos, | 707 void AddFinalParameter(TokenPosition name_pos, |
| 705 const String* name, | 708 const String* name, |
| 706 const AbstractType* type) { | 709 const AbstractType* type) { |
| 707 this->num_fixed_parameters++; | 710 this->num_fixed_parameters++; |
| 708 ParamDesc param; | 711 ParamDesc param; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 } | 753 } |
| 751 | 754 |
| 752 void SetImplicitlyFinal() { implicitly_final = true; } | 755 void SetImplicitlyFinal() { implicitly_final = true; } |
| 753 | 756 |
| 754 int num_fixed_parameters; | 757 int num_fixed_parameters; |
| 755 int num_optional_parameters; | 758 int num_optional_parameters; |
| 756 bool has_optional_positional_parameters; | 759 bool has_optional_positional_parameters; |
| 757 bool has_optional_named_parameters; | 760 bool has_optional_named_parameters; |
| 758 bool has_explicit_default_values; | 761 bool has_explicit_default_values; |
| 759 bool has_field_initializer; | 762 bool has_field_initializer; |
| 763 bool has_covariant; | |
| 760 bool implicitly_final; | 764 bool implicitly_final; |
| 761 bool skipped; | 765 bool skipped; |
| 762 ZoneGrowableArray<ParamDesc>* parameters; | 766 ZoneGrowableArray<ParamDesc>* parameters; |
| 763 }; | 767 }; |
| 764 | 768 |
| 765 | 769 |
| 766 struct MemberDesc { | 770 struct MemberDesc { |
| 767 MemberDesc() { Clear(); } | 771 MemberDesc() { Clear(); } |
| 768 | 772 |
| 769 void Clear() { | 773 void Clear() { |
| 770 has_abstract = false; | 774 has_abstract = false; |
| 771 has_external = false; | 775 has_external = false; |
| 776 has_covariant = false; | |
| 772 has_final = false; | 777 has_final = false; |
| 773 has_const = false; | 778 has_const = false; |
| 774 has_static = false; | 779 has_static = false; |
| 775 has_var = false; | 780 has_var = false; |
| 776 has_factory = false; | 781 has_factory = false; |
| 777 has_operator = false; | 782 has_operator = false; |
| 778 has_native = false; | 783 has_native = false; |
| 779 metadata_pos = TokenPosition::kNoSource; | 784 metadata_pos = TokenPosition::kNoSource; |
| 780 operator_token = Token::kILLEGAL; | 785 operator_token = Token::kILLEGAL; |
| 781 type = NULL; | 786 type = NULL; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 809 } else if (IsGetter()) { | 814 } else if (IsGetter()) { |
| 810 return "getter"; | 815 return "getter"; |
| 811 } else if (IsSetter()) { | 816 } else if (IsSetter()) { |
| 812 return "setter"; | 817 return "setter"; |
| 813 } | 818 } |
| 814 return "method"; | 819 return "method"; |
| 815 } | 820 } |
| 816 String* DictName() const { return (dict_name != NULL) ? dict_name : name; } | 821 String* DictName() const { return (dict_name != NULL) ? dict_name : name; } |
| 817 bool has_abstract; | 822 bool has_abstract; |
| 818 bool has_external; | 823 bool has_external; |
| 824 bool has_covariant; | |
| 819 bool has_final; | 825 bool has_final; |
| 820 bool has_const; | 826 bool has_const; |
| 821 bool has_static; | 827 bool has_static; |
| 822 bool has_var; | 828 bool has_var; |
| 823 bool has_factory; | 829 bool has_factory; |
| 824 bool has_operator; | 830 bool has_operator; |
| 825 bool has_native; | 831 bool has_native; |
| 826 TokenPosition metadata_pos; | 832 TokenPosition metadata_pos; |
| 827 Token::Kind operator_token; | 833 Token::Kind operator_token; |
| 828 const AbstractType* type; | 834 const AbstractType* type; |
| (...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1939 bool var_seen = false; | 1945 bool var_seen = false; |
| 1940 bool final_seen = false; | 1946 bool final_seen = false; |
| 1941 bool this_seen = false; | 1947 bool this_seen = false; |
| 1942 | 1948 |
| 1943 if (evaluate_metadata && (CurrentToken() == Token::kAT)) { | 1949 if (evaluate_metadata && (CurrentToken() == Token::kAT)) { |
| 1944 parameter.metadata = &Array::ZoneHandle(Z, EvaluateMetadata()); | 1950 parameter.metadata = &Array::ZoneHandle(Z, EvaluateMetadata()); |
| 1945 } else { | 1951 } else { |
| 1946 SkipMetadata(); | 1952 SkipMetadata(); |
| 1947 } | 1953 } |
| 1948 | 1954 |
| 1955 if (CurrentToken() == Token::kCOVARIANT && | |
| 1956 (LookaheadToken(1) == Token::kFINAL || LookaheadToken(1) == Token::kVAR || | |
| 1957 Token::IsIdentifier(LookaheadToken(1)))) { | |
| 1958 parameter.is_covariant = true; | |
| 1959 ConsumeToken(); | |
| 1960 } | |
| 1949 if (CurrentToken() == Token::kFINAL) { | 1961 if (CurrentToken() == Token::kFINAL) { |
| 1950 ConsumeToken(); | 1962 ConsumeToken(); |
| 1951 final_seen = true; | 1963 final_seen = true; |
| 1952 parameter.is_final = true; | 1964 parameter.is_final = true; |
| 1953 } else if (CurrentToken() == Token::kVAR) { | 1965 } else if (CurrentToken() == Token::kVAR) { |
| 1954 ConsumeToken(); | 1966 ConsumeToken(); |
| 1955 var_seen = true; | 1967 var_seen = true; |
| 1956 // The parameter type is the 'dynamic' type. | 1968 // The parameter type is the 'dynamic' type. |
| 1957 // If this is an initializing formal, its type will be set to the type of | 1969 // If this is an initializing formal, its type will be set to the type of |
| 1958 // the respective field when the constructor is fully parsed. | 1970 // the respective field when the constructor is fully parsed. |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2156 } | 2168 } |
| 2157 } | 2169 } |
| 2158 if (parameter.type->IsVoidType()) { | 2170 if (parameter.type->IsVoidType()) { |
| 2159 ReportError("parameter '%s' may not be 'void'", | 2171 ReportError("parameter '%s' may not be 'void'", |
| 2160 parameter.name->ToCString()); | 2172 parameter.name->ToCString()); |
| 2161 } | 2173 } |
| 2162 if (params->implicitly_final) { | 2174 if (params->implicitly_final) { |
| 2163 parameter.is_final = true; | 2175 parameter.is_final = true; |
| 2164 } | 2176 } |
| 2165 params->parameters->Add(parameter); | 2177 params->parameters->Add(parameter); |
| 2178 if (parameter.is_covariant) { | |
| 2179 params->has_covariant = true; | |
| 2180 } | |
| 2166 } | 2181 } |
| 2167 | 2182 |
| 2168 | 2183 |
| 2169 // Parses a sequence of normal or optional formal parameters. | 2184 // Parses a sequence of normal or optional formal parameters. |
| 2170 void Parser::ParseFormalParameters(bool allow_explicit_default_values, | 2185 void Parser::ParseFormalParameters(bool allow_explicit_default_values, |
| 2171 bool evaluate_metadata, | 2186 bool evaluate_metadata, |
| 2172 ParamList* params) { | 2187 ParamList* params) { |
| 2173 TRACE_PARSER("ParseFormalParameters"); | 2188 TRACE_PARSER("ParseFormalParameters"); |
| 2174 // Optional parameter lists cannot be empty. | 2189 // Optional parameter lists cannot be empty. |
| 2175 // The completely empty parameter list is handled before getting here. | 2190 // The completely empty parameter list is handled before getting here. |
| (...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3667 | 3682 |
| 3668 | 3683 |
| 3669 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3684 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 3670 TRACE_PARSER("ParseMethodOrConstructor"); | 3685 TRACE_PARSER("ParseMethodOrConstructor"); |
| 3671 // We are at the beginning of the formal parameters list. | 3686 // We are at the beginning of the formal parameters list. |
| 3672 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || | 3687 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT || |
| 3673 method->IsGetter()); | 3688 method->IsGetter()); |
| 3674 ASSERT(method->type != NULL); // May still be unresolved. | 3689 ASSERT(method->type != NULL); // May still be unresolved. |
| 3675 ASSERT(current_member_ == method); | 3690 ASSERT(current_member_ == method); |
| 3676 | 3691 |
| 3692 if (method->has_covariant) { | |
| 3693 ReportError(method->name_pos, | |
| 3694 "methods and constructors cannot be declared covariant"); | |
|
regis
2017/01/12 18:17:58
remove extra space
| |
| 3695 } | |
| 3677 if (method->has_var) { | 3696 if (method->has_var) { |
| 3678 ReportError(method->name_pos, "keyword var not allowed for methods"); | 3697 ReportError(method->name_pos, "keyword var not allowed for methods"); |
| 3679 } | 3698 } |
| 3680 if (method->has_final) { | 3699 if (method->has_final) { |
| 3681 ReportError(method->name_pos, "'final' not allowed for methods"); | 3700 ReportError(method->name_pos, "'final' not allowed for methods"); |
| 3682 } | 3701 } |
| 3683 if (method->has_abstract && method->has_static) { | 3702 if (method->has_abstract && method->has_static) { |
| 3684 ReportError(method->name_pos, "static method '%s' cannot be abstract", | 3703 ReportError(method->name_pos, "static method '%s' cannot be abstract", |
| 3685 method->name->ToCString()); | 3704 method->name->ToCString()); |
| 3686 } | 3705 } |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4034 // The parser has read the first field name and is now at the token | 4053 // The parser has read the first field name and is now at the token |
| 4035 // after the field name. | 4054 // after the field name. |
| 4036 ASSERT(CurrentToken() == Token::kSEMICOLON || | 4055 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 4037 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); | 4056 CurrentToken() == Token::kCOMMA || CurrentToken() == Token::kASSIGN); |
| 4038 ASSERT(field->type != NULL); | 4057 ASSERT(field->type != NULL); |
| 4039 ASSERT(field->name_pos.IsReal()); | 4058 ASSERT(field->name_pos.IsReal()); |
| 4040 ASSERT(current_member_ == field); | 4059 ASSERT(current_member_ == field); |
| 4041 // All const fields are also final. | 4060 // All const fields are also final. |
| 4042 ASSERT(!field->has_const || field->has_final); | 4061 ASSERT(!field->has_const || field->has_final); |
| 4043 | 4062 |
| 4063 if (field->has_covariant) { | |
| 4064 if (field->has_static) { | |
| 4065 ReportError("static fields cannot be declared covariant"); | |
| 4066 } else if (field->has_final) { | |
| 4067 ReportError("final fields cannot be declared covariant"); | |
| 4068 } | |
| 4069 } | |
| 4044 if (field->has_abstract) { | 4070 if (field->has_abstract) { |
| 4045 ReportError("keyword 'abstract' not allowed in field declaration"); | 4071 ReportError("keyword 'abstract' not allowed in field declaration"); |
| 4046 } | 4072 } |
| 4047 if (field->has_external) { | 4073 if (field->has_external) { |
| 4048 ReportError("keyword 'external' not allowed in field declaration"); | 4074 ReportError("keyword 'external' not allowed in field declaration"); |
| 4049 } | 4075 } |
| 4050 if (field->has_factory) { | 4076 if (field->has_factory) { |
| 4051 ReportError("keyword 'factory' not allowed in field declaration"); | 4077 ReportError("keyword 'factory' not allowed in field declaration"); |
| 4052 } | 4078 } |
| 4053 if (!field->has_static && field->has_const) { | 4079 if (!field->has_static && field->has_const) { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4245 if ((CurrentToken() == Token::kEXTERNAL) && | 4271 if ((CurrentToken() == Token::kEXTERNAL) && |
| 4246 (LookaheadToken(1) != Token::kLPAREN)) { | 4272 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4247 ConsumeToken(); | 4273 ConsumeToken(); |
| 4248 member.has_external = true; | 4274 member.has_external = true; |
| 4249 } | 4275 } |
| 4250 if ((CurrentToken() == Token::kSTATIC) && | 4276 if ((CurrentToken() == Token::kSTATIC) && |
| 4251 (LookaheadToken(1) != Token::kLPAREN)) { | 4277 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4252 ConsumeToken(); | 4278 ConsumeToken(); |
| 4253 member.has_static = true; | 4279 member.has_static = true; |
| 4254 } | 4280 } |
| 4281 if (CurrentToken() == Token::kCOVARIANT) { | |
| 4282 ConsumeToken(); | |
| 4283 member.has_covariant = true; | |
| 4284 } | |
| 4255 if (CurrentToken() == Token::kCONST) { | 4285 if (CurrentToken() == Token::kCONST) { |
| 4256 ConsumeToken(); | 4286 ConsumeToken(); |
| 4257 member.has_const = true; | 4287 member.has_const = true; |
| 4258 } else if (CurrentToken() == Token::kFINAL) { | 4288 } else if (CurrentToken() == Token::kFINAL) { |
| 4259 ConsumeToken(); | 4289 ConsumeToken(); |
| 4260 member.has_final = true; | 4290 member.has_final = true; |
| 4261 } | 4291 } |
| 4262 if (CurrentToken() == Token::kVAR) { | 4292 if (CurrentToken() == Token::kVAR) { |
| 4263 if (member.has_const) { | 4293 if (member.has_const) { |
| 4264 ReportError("identifier expected after 'const'"); | 4294 ReportError("identifier expected after 'const'"); |
| (...skipping 3041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7306 for (int i = 0; i < num_parameters; i++) { | 7336 for (int i = 0; i < num_parameters; i++) { |
| 7307 ParamDesc& param_desc = (*params->parameters)[i]; | 7337 ParamDesc& param_desc = (*params->parameters)[i]; |
| 7308 func.SetParameterTypeAt(i, *param_desc.type); | 7338 func.SetParameterTypeAt(i, *param_desc.type); |
| 7309 func.SetParameterNameAt(i, *param_desc.name); | 7339 func.SetParameterNameAt(i, *param_desc.name); |
| 7310 if (param_desc.is_field_initializer && !func.IsGenerativeConstructor()) { | 7340 if (param_desc.is_field_initializer && !func.IsGenerativeConstructor()) { |
| 7311 // Redirecting constructors are detected later in ParseConstructor. | 7341 // Redirecting constructors are detected later in ParseConstructor. |
| 7312 ReportError(param_desc.name_pos, | 7342 ReportError(param_desc.name_pos, |
| 7313 "only generative constructors may have " | 7343 "only generative constructors may have " |
| 7314 "initializing formal parameters"); | 7344 "initializing formal parameters"); |
| 7315 } | 7345 } |
| 7346 if (param_desc.is_covariant) { | |
| 7347 if (!func.IsDynamicFunction(true)) { | |
| 7348 ReportError(param_desc.name_pos, | |
| 7349 "only instance functions may have " | |
| 7350 "covariant parameters"); | |
| 7351 } | |
| 7352 } | |
| 7316 } | 7353 } |
| 7317 } | 7354 } |
| 7318 | 7355 |
| 7319 | 7356 |
| 7320 // Populate local scope with the formal parameters. | 7357 // Populate local scope with the formal parameters. |
| 7321 void Parser::AddFormalParamsToScope(const ParamList* params, | 7358 void Parser::AddFormalParamsToScope(const ParamList* params, |
| 7322 LocalScope* scope) { | 7359 LocalScope* scope) { |
| 7323 ASSERT((params != NULL) && (params->parameters != NULL)); | 7360 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 7324 ASSERT(scope != NULL); | 7361 ASSERT(scope != NULL); |
| 7325 const int num_parameters = params->parameters->length(); | 7362 const int num_parameters = params->parameters->length(); |
| (...skipping 7298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14624 const ArgumentListNode& function_args, | 14661 const ArgumentListNode& function_args, |
| 14625 const LocalVariable* temp_for_last_arg, | 14662 const LocalVariable* temp_for_last_arg, |
| 14626 bool is_super_invocation) { | 14663 bool is_super_invocation) { |
| 14627 UNREACHABLE(); | 14664 UNREACHABLE(); |
| 14628 return NULL; | 14665 return NULL; |
| 14629 } | 14666 } |
| 14630 | 14667 |
| 14631 } // namespace dart | 14668 } // namespace dart |
| 14632 | 14669 |
| 14633 #endif // DART_PRECOMPILED_RUNTIME | 14670 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |