| 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 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 | 1013 |
| 1014 void Parser::ParseFormalParameter(bool allow_explicit_default_value, | 1014 void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
| 1015 ParamList* params) { | 1015 ParamList* params) { |
| 1016 TRACE_PARSER("ParseFormalParameter"); | 1016 TRACE_PARSER("ParseFormalParameter"); |
| 1017 ParamDesc parameter; | 1017 ParamDesc parameter; |
| 1018 bool var_seen = false; | 1018 bool var_seen = false; |
| 1019 bool this_seen = false; | 1019 bool this_seen = false; |
| 1020 | 1020 |
| 1021 SkipMetadata(); |
| 1021 if (CurrentToken() == Token::kFINAL) { | 1022 if (CurrentToken() == Token::kFINAL) { |
| 1022 ConsumeToken(); | 1023 ConsumeToken(); |
| 1023 parameter.is_final = true; | 1024 parameter.is_final = true; |
| 1024 } else if (CurrentToken() == Token::kVAR) { | 1025 } else if (CurrentToken() == Token::kVAR) { |
| 1025 ConsumeToken(); | 1026 ConsumeToken(); |
| 1026 var_seen = true; | 1027 var_seen = true; |
| 1027 // The parameter type is the 'Dynamic' type. | 1028 // The parameter type is the 'Dynamic' type. |
| 1028 parameter.type = &Type::ZoneHandle(Type::DynamicType()); | 1029 parameter.type = &Type::ZoneHandle(Type::DynamicType()); |
| 1029 } | 1030 } |
| 1030 if (CurrentToken() == Token::kTHIS) { | 1031 if (CurrentToken() == Token::kTHIS) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 ASSERT(params->num_optional_parameters == 0); | 1176 ASSERT(params->num_optional_parameters == 0); |
| 1176 } | 1177 } |
| 1177 } | 1178 } |
| 1178 if (parameter.type->IsVoidType()) { | 1179 if (parameter.type->IsVoidType()) { |
| 1179 ErrorMsg("parameter '%s' may not be 'void'", parameter.name->ToCString()); | 1180 ErrorMsg("parameter '%s' may not be 'void'", parameter.name->ToCString()); |
| 1180 } | 1181 } |
| 1181 params->parameters->Add(parameter); | 1182 params->parameters->Add(parameter); |
| 1182 } | 1183 } |
| 1183 | 1184 |
| 1184 | 1185 |
| 1186 // Parses a sequence of normal or optional formal parameters. |
| 1187 void Parser::ParseFormalParameters(bool allow_explicit_default_values, |
| 1188 ParamList* params) { |
| 1189 TRACE_PARSER("ParseFormalParameters"); |
| 1190 do { |
| 1191 ConsumeToken(); |
| 1192 if (!params->has_optional_positional_parameters && |
| 1193 !params->has_optional_named_parameters && |
| 1194 (CurrentToken() == Token::kLBRACK)) { |
| 1195 // End of normal parameters, start of optional positional parameters. |
| 1196 params->has_optional_positional_parameters = true; |
| 1197 return; |
| 1198 } |
| 1199 if (!params->has_optional_positional_parameters && |
| 1200 !params->has_optional_named_parameters && |
| 1201 (CurrentToken() == Token::kLBRACE)) { |
| 1202 // End of normal parameters, start of optional named parameters. |
| 1203 params->has_optional_named_parameters = true; |
| 1204 return; |
| 1205 } |
| 1206 ParseFormalParameter(allow_explicit_default_values, params); |
| 1207 } while (CurrentToken() == Token::kCOMMA); |
| 1208 } |
| 1209 |
| 1210 |
| 1185 void Parser::ParseFormalParameterList(bool allow_explicit_default_values, | 1211 void Parser::ParseFormalParameterList(bool allow_explicit_default_values, |
| 1186 ParamList* params) { | 1212 ParamList* params) { |
| 1187 TRACE_PARSER("ParseFormalParameterList"); | 1213 TRACE_PARSER("ParseFormalParameterList"); |
| 1188 ASSERT(CurrentToken() == Token::kLPAREN); | 1214 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1189 | 1215 |
| 1190 if (LookaheadToken(1) != Token::kRPAREN) { | 1216 if (LookaheadToken(1) != Token::kRPAREN) { |
| 1191 // Parse fixed parameters. | 1217 // Parse fixed parameters. |
| 1192 ParseFormalParameters(allow_explicit_default_values, params); | 1218 ParseFormalParameters(allow_explicit_default_values, params); |
| 1193 if (params->has_optional_positional_parameters || | 1219 if (params->has_optional_positional_parameters || |
| 1194 params->has_optional_named_parameters) { | 1220 params->has_optional_named_parameters) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1210 !params->has_optional_named_parameters) { | 1236 !params->has_optional_named_parameters) { |
| 1211 ErrorMsg("',' or ')' expected"); | 1237 ErrorMsg("',' or ')' expected"); |
| 1212 } | 1238 } |
| 1213 } else { | 1239 } else { |
| 1214 ConsumeToken(); | 1240 ConsumeToken(); |
| 1215 } | 1241 } |
| 1216 ExpectToken(Token::kRPAREN); | 1242 ExpectToken(Token::kRPAREN); |
| 1217 } | 1243 } |
| 1218 | 1244 |
| 1219 | 1245 |
| 1220 // Parses a sequence of normal or optional formal parameters. | |
| 1221 void Parser::ParseFormalParameters(bool allow_explicit_default_values, | |
| 1222 ParamList* params) { | |
| 1223 TRACE_PARSER("ParseFormalParameters"); | |
| 1224 do { | |
| 1225 ConsumeToken(); | |
| 1226 if (!params->has_optional_positional_parameters && | |
| 1227 !params->has_optional_named_parameters && | |
| 1228 (CurrentToken() == Token::kLBRACK)) { | |
| 1229 // End of normal parameters, start of optional positional parameters. | |
| 1230 params->has_optional_positional_parameters = true; | |
| 1231 return; | |
| 1232 } | |
| 1233 if (!params->has_optional_positional_parameters && | |
| 1234 !params->has_optional_named_parameters && | |
| 1235 (CurrentToken() == Token::kLBRACE)) { | |
| 1236 // End of normal parameters, start of optional named parameters. | |
| 1237 params->has_optional_named_parameters = true; | |
| 1238 return; | |
| 1239 } | |
| 1240 ParseFormalParameter(allow_explicit_default_values, params); | |
| 1241 } while (CurrentToken() == Token::kCOMMA); | |
| 1242 } | |
| 1243 | |
| 1244 | |
| 1245 String& Parser::ParseNativeDeclaration() { | 1246 String& Parser::ParseNativeDeclaration() { |
| 1246 TRACE_PARSER("ParseNativeDeclaration"); | 1247 TRACE_PARSER("ParseNativeDeclaration"); |
| 1247 ASSERT(IsLiteral("native")); | 1248 ASSERT(IsLiteral("native")); |
| 1248 ConsumeToken(); | 1249 ConsumeToken(); |
| 1249 if (CurrentToken() != Token::kSTRING) { | 1250 if (CurrentToken() != Token::kSTRING) { |
| 1250 ErrorMsg("string literal expected"); | 1251 ErrorMsg("string literal expected"); |
| 1251 } | 1252 } |
| 1252 String& native_name = *CurrentLiteral(); | 1253 String& native_name = *CurrentLiteral(); |
| 1253 ConsumeToken(); | 1254 ConsumeToken(); |
| 1254 ExpectSemicolon(); | 1255 ExpectSemicolon(); |
| (...skipping 1856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 if (CurrentToken() == Token::kIMPLEMENTS) { | 3112 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3112 Array& interfaces = Array::Handle(); | 3113 Array& interfaces = Array::Handle(); |
| 3113 const intptr_t interfaces_pos = TokenPos(); | 3114 const intptr_t interfaces_pos = TokenPos(); |
| 3114 interfaces = ParseInterfaceList(); | 3115 interfaces = ParseInterfaceList(); |
| 3115 AddInterfaces(interfaces_pos, cls, interfaces); | 3116 AddInterfaces(interfaces_pos, cls, interfaces); |
| 3116 } | 3117 } |
| 3117 | 3118 |
| 3118 ExpectToken(Token::kLBRACE); | 3119 ExpectToken(Token::kLBRACE); |
| 3119 ClassDesc members(cls, class_name, false, class_pos); | 3120 ClassDesc members(cls, class_name, false, class_pos); |
| 3120 while (CurrentToken() != Token::kRBRACE) { | 3121 while (CurrentToken() != Token::kRBRACE) { |
| 3122 SkipMetadata(); |
| 3121 ParseClassMemberDefinition(&members); | 3123 ParseClassMemberDefinition(&members); |
| 3122 } | 3124 } |
| 3123 ExpectToken(Token::kRBRACE); | 3125 ExpectToken(Token::kRBRACE); |
| 3124 | 3126 |
| 3125 if (is_abstract || members.is_abstract()) { | 3127 if (is_abstract || members.is_abstract()) { |
| 3126 cls.set_is_abstract(); | 3128 cls.set_is_abstract(); |
| 3127 } | 3129 } |
| 3128 | 3130 |
| 3129 // Add an implicit constructor if no explicit constructor is present. No | 3131 // Add an implicit constructor if no explicit constructor is present. No |
| 3130 // implicit constructors are needed for patch classes. | 3132 // implicit constructors are needed for patch classes. |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3474 if (token_kind_ == Token::kGT) { | 3476 if (token_kind_ == Token::kGT) { |
| 3475 ConsumeToken(); | 3477 ConsumeToken(); |
| 3476 } else if (token_kind_ == Token::kSHR) { | 3478 } else if (token_kind_ == Token::kSHR) { |
| 3477 token_kind_ = Token::kGT; | 3479 token_kind_ = Token::kGT; |
| 3478 } else { | 3480 } else { |
| 3479 UNREACHABLE(); | 3481 UNREACHABLE(); |
| 3480 } | 3482 } |
| 3481 } | 3483 } |
| 3482 | 3484 |
| 3483 | 3485 |
| 3486 void Parser::SkipMetadata() { |
| 3487 while (CurrentToken() == Token::kAT) { |
| 3488 ConsumeToken(); |
| 3489 ExpectIdentifier("identifier expected"); |
| 3490 if (CurrentToken() == Token::kPERIOD) { |
| 3491 ConsumeToken(); |
| 3492 ExpectIdentifier("identifier expected"); |
| 3493 if (CurrentToken() == Token::kPERIOD) { |
| 3494 ConsumeToken(); |
| 3495 ExpectIdentifier("identifier expected"); |
| 3496 } |
| 3497 } |
| 3498 if (CurrentToken() == Token::kLPAREN) { |
| 3499 SkipToMatchingParenthesis(); |
| 3500 } |
| 3501 } |
| 3502 } |
| 3503 |
| 3504 |
| 3484 void Parser::SkipTypeArguments() { | 3505 void Parser::SkipTypeArguments() { |
| 3485 if (CurrentToken() == Token::kLT) { | 3506 if (CurrentToken() == Token::kLT) { |
| 3486 do { | 3507 do { |
| 3487 ConsumeToken(); | 3508 ConsumeToken(); |
| 3488 SkipType(false); | 3509 SkipType(false); |
| 3489 } while (CurrentToken() == Token::kCOMMA); | 3510 } while (CurrentToken() == Token::kCOMMA); |
| 3490 Token::Kind token = CurrentToken(); | 3511 Token::Kind token = CurrentToken(); |
| 3491 if ((token == Token::kGT) || (token == Token::kSHR)) { | 3512 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 3492 ConsumeRightAngleBracket(); | 3513 ConsumeRightAngleBracket(); |
| 3493 } else { | 3514 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3519 if (CurrentToken() == Token::kLT) { | 3540 if (CurrentToken() == Token::kLT) { |
| 3520 const GrowableObjectArray& type_parameters_array = | 3541 const GrowableObjectArray& type_parameters_array = |
| 3521 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3542 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3522 intptr_t index = 0; | 3543 intptr_t index = 0; |
| 3523 TypeParameter& type_parameter = TypeParameter::Handle(); | 3544 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 3524 TypeParameter& existing_type_parameter = TypeParameter::Handle(); | 3545 TypeParameter& existing_type_parameter = TypeParameter::Handle(); |
| 3525 String& existing_type_parameter_name = String::Handle(); | 3546 String& existing_type_parameter_name = String::Handle(); |
| 3526 AbstractType& type_parameter_bound = Type::Handle(); | 3547 AbstractType& type_parameter_bound = Type::Handle(); |
| 3527 do { | 3548 do { |
| 3528 ConsumeToken(); | 3549 ConsumeToken(); |
| 3550 SkipMetadata(); |
| 3529 if (CurrentToken() != Token::kIDENT) { | 3551 if (CurrentToken() != Token::kIDENT) { |
| 3530 ErrorMsg("type parameter name expected"); | 3552 ErrorMsg("type parameter name expected"); |
| 3531 } | 3553 } |
| 3532 String& type_parameter_name = *CurrentLiteral(); | 3554 String& type_parameter_name = *CurrentLiteral(); |
| 3533 const intptr_t type_parameter_pos = TokenPos(); | 3555 const intptr_t type_parameter_pos = TokenPos(); |
| 3534 // Check for duplicate type parameters. | 3556 // Check for duplicate type parameters. |
| 3535 for (intptr_t i = 0; i < index; i++) { | 3557 for (intptr_t i = 0; i < index; i++) { |
| 3536 existing_type_parameter ^= type_parameters_array.At(i); | 3558 existing_type_parameter ^= type_parameters_array.At(i); |
| 3537 existing_type_parameter_name = existing_type_parameter.name(); | 3559 existing_type_parameter_name = existing_type_parameter.name(); |
| 3538 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 3560 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4172 Class& toplevel_class = Class::Handle( | 4194 Class& toplevel_class = Class::Handle( |
| 4173 Class::New(String::Handle(Symbols::TopLevel()), script_, TokenPos())); | 4195 Class::New(String::Handle(Symbols::TopLevel()), script_, TokenPos())); |
| 4174 toplevel_class.set_library(library_); | 4196 toplevel_class.set_library(library_); |
| 4175 | 4197 |
| 4176 if (is_library_source()) { | 4198 if (is_library_source()) { |
| 4177 ParseLibraryDefinition(); | 4199 ParseLibraryDefinition(); |
| 4178 } | 4200 } |
| 4179 | 4201 |
| 4180 while (true) { | 4202 while (true) { |
| 4181 set_current_class(Class::Handle()); // No current class. | 4203 set_current_class(Class::Handle()); // No current class. |
| 4204 SkipMetadata(); |
| 4182 if (CurrentToken() == Token::kCLASS) { | 4205 if (CurrentToken() == Token::kCLASS) { |
| 4183 ParseClassDefinition(pending_classes); | 4206 ParseClassDefinition(pending_classes); |
| 4184 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4207 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4185 (LookaheadToken(1) != Token::kLPAREN)) { | 4208 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4186 ParseFunctionTypeAlias(pending_classes); | 4209 ParseFunctionTypeAlias(pending_classes); |
| 4187 } else if (CurrentToken() == Token::kINTERFACE) { | 4210 } else if (CurrentToken() == Token::kINTERFACE) { |
| 4188 ParseInterfaceDefinition(pending_classes); | 4211 ParseInterfaceDefinition(pending_classes); |
| 4189 } else if ((CurrentToken() == Token::kABSTRACT) && | 4212 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4190 (LookaheadToken(1) == Token::kCLASS)) { | 4213 (LookaheadToken(1) == Token::kCLASS)) { |
| 4191 ParseClassDefinition(pending_classes); | 4214 ParseClassDefinition(pending_classes); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4534 } | 4557 } |
| 4535 return ParseType(finalization); | 4558 return ParseType(finalization); |
| 4536 } | 4559 } |
| 4537 | 4560 |
| 4538 | 4561 |
| 4539 // Returns ast nodes of the variable initialization. Variables without an | 4562 // Returns ast nodes of the variable initialization. Variables without an |
| 4540 // explicit initializer are initialized to null. If several variables are | 4563 // explicit initializer are initialized to null. If several variables are |
| 4541 // declared, the individual initializers are collected in a sequence node. | 4564 // declared, the individual initializers are collected in a sequence node. |
| 4542 AstNode* Parser::ParseVariableDeclarationList() { | 4565 AstNode* Parser::ParseVariableDeclarationList() { |
| 4543 TRACE_PARSER("ParseVariableDeclarationList"); | 4566 TRACE_PARSER("ParseVariableDeclarationList"); |
| 4567 SkipMetadata(); |
| 4544 bool is_final = (CurrentToken() == Token::kFINAL); | 4568 bool is_final = (CurrentToken() == Token::kFINAL); |
| 4545 bool is_const = (CurrentToken() == Token::kCONST); | 4569 bool is_const = (CurrentToken() == Token::kCONST); |
| 4546 const AbstractType& type = AbstractType::ZoneHandle(ParseConstFinalVarOrType( | 4570 const AbstractType& type = AbstractType::ZoneHandle(ParseConstFinalVarOrType( |
| 4547 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 4571 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
| 4548 ClassFinalizer::kIgnore)); | 4572 ClassFinalizer::kIgnore)); |
| 4549 if (!IsIdentifier()) { | 4573 if (!IsIdentifier()) { |
| 4550 ErrorMsg("identifier expected"); | 4574 ErrorMsg("identifier expected"); |
| 4551 } | 4575 } |
| 4552 | 4576 |
| 4553 AstNode* initializers = ParseVariableDeclaration(type, is_final, is_const); | 4577 AstNode* initializers = ParseVariableDeclaration(type, is_final, is_const); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4857 ConsumeToken(); | 4881 ConsumeToken(); |
| 4858 return true; | 4882 return true; |
| 4859 } else if (CurrentToken() == Token::kIDENT) { | 4883 } else if (CurrentToken() == Token::kIDENT) { |
| 4860 return TryParseOptionalType(); | 4884 return TryParseOptionalType(); |
| 4861 } | 4885 } |
| 4862 return false; | 4886 return false; |
| 4863 } | 4887 } |
| 4864 | 4888 |
| 4865 | 4889 |
| 4866 // Look ahead to detect whether the next tokens should be parsed as | 4890 // Look ahead to detect whether the next tokens should be parsed as |
| 4867 // a variable declaration. Returns true if we detect the token pattern: | 4891 // a variable declaration. Ignores optional metadata. |
| 4892 // Returns true if we detect the token pattern: |
| 4868 // 'var' | 4893 // 'var' |
| 4869 // | 'final' | 4894 // | 'final' |
| 4870 // | const [type] ident (';' | '=' | ',') | 4895 // | const [type] ident (';' | '=' | ',') |
| 4871 // | type ident (';' | '=' | ',') | 4896 // | type ident (';' | '=' | ',') |
| 4872 // Token position remains unchanged. | 4897 // Token position remains unchanged. |
| 4873 bool Parser::IsVariableDeclaration() { | 4898 bool Parser::IsVariableDeclaration() { |
| 4874 if ((CurrentToken() == Token::kVAR) || | 4899 if ((CurrentToken() == Token::kVAR) || |
| 4875 (CurrentToken() == Token::kFINAL)) { | 4900 (CurrentToken() == Token::kFINAL)) { |
| 4876 return true; | 4901 return true; |
| 4877 } | 4902 } |
| 4903 // Skip optional metadata. |
| 4904 if (CurrentToken() == Token::kAT) { |
| 4905 const intptr_t saved_pos = TokenPos(); |
| 4906 SkipMetadata(); |
| 4907 const bool is_var_decl = IsVariableDeclaration(); |
| 4908 SetPosition(saved_pos); |
| 4909 return is_var_decl; |
| 4910 } |
| 4878 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { | 4911 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { |
| 4879 // Not a legal type identifier or const keyword | 4912 // Not a legal type identifier or const keyword or metadata |
| 4880 return false; | 4913 return false; |
| 4881 } | 4914 } |
| 4882 const intptr_t saved_pos = TokenPos(); | 4915 const intptr_t saved_pos = TokenPos(); |
| 4883 bool is_var_decl = false; | 4916 bool is_var_decl = false; |
| 4884 bool have_type = false; | 4917 bool have_type = false; |
| 4885 if (CurrentToken() == Token::kCONST) { | 4918 if (CurrentToken() == Token::kCONST) { |
| 4886 ConsumeToken(); | 4919 ConsumeToken(); |
| 4887 have_type = true; // Type is Dynamic. | 4920 have_type = true; // Type is Dynamic. |
| 4888 } | 4921 } |
| 4889 if (IsIdentifier()) { // Type or variable name. | 4922 if (IsIdentifier()) { // Type or variable name. |
| (...skipping 4547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9437 void Parser::SkipQualIdent() { | 9470 void Parser::SkipQualIdent() { |
| 9438 ASSERT(IsIdentifier()); | 9471 ASSERT(IsIdentifier()); |
| 9439 ConsumeToken(); | 9472 ConsumeToken(); |
| 9440 if (CurrentToken() == Token::kPERIOD) { | 9473 if (CurrentToken() == Token::kPERIOD) { |
| 9441 ConsumeToken(); // Consume the kPERIOD token. | 9474 ConsumeToken(); // Consume the kPERIOD token. |
| 9442 ExpectIdentifier("identifier expected after '.'"); | 9475 ExpectIdentifier("identifier expected after '.'"); |
| 9443 } | 9476 } |
| 9444 } | 9477 } |
| 9445 | 9478 |
| 9446 } // namespace dart | 9479 } // namespace dart |
| OLD | NEW |