Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: runtime/vm/parser.cc

Issue 2625823004: Support covariant keyword in the VM parser (Closed)
Patch Set: Fix tests that rely on token position Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/method_recognizer.h ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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");
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/method_recognizer.h ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698