| OLD | NEW |
| 1 // Copyright (c) 2011, 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" |
| 11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 } | 239 } |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 Token::Kind Parser::CurrentToken() { | 243 Token::Kind Parser::CurrentToken() { |
| 244 if (token_kind_ == Token::kILLEGAL) { | 244 if (token_kind_ == Token::kILLEGAL) { |
| 245 token_kind_ = tokens_.KindAt(token_index_); | 245 token_kind_ = tokens_.KindAt(token_index_); |
| 246 if (token_kind_ == Token::kERROR) { | 246 if (token_kind_ == Token::kERROR) { |
| 247 ErrorMsg(token_index_, CurrentLiteral()->ToCString()); | 247 ErrorMsg(token_index_, CurrentLiteral()->ToCString()); |
| 248 } | 248 } |
| 249 if (Token::IsPseudoKeyword(token_kind_) && !is_top_level_) { | |
| 250 token_kind_ = Token::kIDENT; | |
| 251 } | |
| 252 } | 249 } |
| 253 CompilerStats::num_token_checks++; | 250 CompilerStats::num_token_checks++; |
| 254 return token_kind_; | 251 return token_kind_; |
| 255 } | 252 } |
| 256 | 253 |
| 257 | 254 |
| 258 Token::Kind Parser::LookaheadToken(int num_tokens) { | 255 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| 259 CompilerStats::num_tokens_lookahead++; | 256 CompilerStats::num_tokens_lookahead++; |
| 260 CompilerStats::num_token_checks++; | 257 CompilerStats::num_token_checks++; |
| 261 return tokens_.KindAt(token_index_ + num_tokens); | 258 return tokens_.KindAt(token_index_ + num_tokens); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 ParamList params; | 627 ParamList params; |
| 631 ASSERT(func.num_fixed_parameters() == 0); // static. | 628 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 632 ASSERT(func.num_optional_parameters() == 0); | 629 ASSERT(func.num_optional_parameters() == 0); |
| 633 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 630 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 634 | 631 |
| 635 // Build local scope for function and populate with the formal parameters. | 632 // Build local scope for function and populate with the formal parameters. |
| 636 OpenFunctionBlock(func); | 633 OpenFunctionBlock(func); |
| 637 AddFormalParamsToScope(¶ms, current_block_->scope); | 634 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 638 | 635 |
| 639 // Static const fields must have an initializer. | 636 // Static const fields must have an initializer. |
| 640 ExpectToken(Token::kIDENT); | 637 ExpectIdentifier("field name expected"); |
| 641 ExpectToken(Token::kASSIGN); | 638 ExpectToken(Token::kASSIGN); |
| 642 | 639 |
| 643 // We don't want to use ParseConstExpr() here because we don't want | 640 // We don't want to use ParseConstExpr() here because we don't want |
| 644 // the constant folding code to create, compile and execute a code | 641 // the constant folding code to create, compile and execute a code |
| 645 // fragment to evaluate the expression. Instead, we just make sure | 642 // fragment to evaluate the expression. Instead, we just make sure |
| 646 // the static const field initializer is a constant expression and | 643 // the static const field initializer is a constant expression and |
| 647 // leave the evaluation to the getter function. | 644 // leave the evaluation to the getter function. |
| 648 const intptr_t expr_pos = token_index_; | 645 const intptr_t expr_pos = token_index_; |
| 649 AstNode* expr = ParseExpr(kAllowConst); | 646 AstNode* expr = ParseExpr(kAllowConst); |
| 650 if (expr->EvalConstExpr() == NULL) { | 647 if (expr->EvalConstExpr() == NULL) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 670 | 667 |
| 671 // Build local scope for function and populate with the formal parameters. | 668 // Build local scope for function and populate with the formal parameters. |
| 672 OpenFunctionBlock(func); | 669 OpenFunctionBlock(func); |
| 673 AddFormalParamsToScope(¶ms, current_block_->scope); | 670 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 674 | 671 |
| 675 // Receiver is local 0. | 672 // Receiver is local 0. |
| 676 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 673 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 677 LoadLocalNode* load_receiver = new LoadLocalNode(token_index_, *receiver); | 674 LoadLocalNode* load_receiver = new LoadLocalNode(token_index_, *receiver); |
| 678 // token_index_ is the function's token position which points to the name of | 675 // token_index_ is the function's token position which points to the name of |
| 679 // the field; | 676 // the field; |
| 680 ASSERT(CurrentToken() == Token::kIDENT); | 677 ASSERT(IsIdentifier()); |
| 681 const String& field_name = *CurrentLiteral(); | 678 const String& field_name = *CurrentLiteral(); |
| 682 const Class& field_class = Class::Handle(func.owner()); | 679 const Class& field_class = Class::Handle(func.owner()); |
| 683 const Field& field = | 680 const Field& field = |
| 684 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); | 681 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); |
| 685 | 682 |
| 686 LoadInstanceFieldNode* load_field = | 683 LoadInstanceFieldNode* load_field = |
| 687 new LoadInstanceFieldNode(token_index_, load_receiver, field); | 684 new LoadInstanceFieldNode(token_index_, load_receiver, field); |
| 688 | 685 |
| 689 ReturnNode* return_node = new ReturnNode(token_index_, load_field); | 686 ReturnNode* return_node = new ReturnNode(token_index_, load_field); |
| 690 current_block_->statements->Add(return_node); | 687 current_block_->statements->Add(return_node); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) { | 803 if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) { |
| 807 ConsumeToken(); | 804 ConsumeToken(); |
| 808 // This must later be changed to a closure type if we recognize | 805 // This must later be changed to a closure type if we recognize |
| 809 // a closure/function type parameter. We check this at the end | 806 // a closure/function type parameter. We check this at the end |
| 810 // of ParseFormalParameter. | 807 // of ParseFormalParameter. |
| 811 parameter.type = &Type::ZoneHandle(Type::VoidType()); | 808 parameter.type = &Type::ZoneHandle(Type::VoidType()); |
| 812 } | 809 } |
| 813 if (parameter.type == NULL) { | 810 if (parameter.type == NULL) { |
| 814 // At this point, we must see an identifier for the type or the | 811 // At this point, we must see an identifier for the type or the |
| 815 // function parameter. | 812 // function parameter. |
| 816 if (CurrentToken() != Token::kIDENT) { | 813 if (!IsIdentifier()) { |
| 817 ErrorMsg("parameter name or type expected"); | 814 ErrorMsg("parameter name or type expected"); |
| 818 } | 815 } |
| 819 // We have not seen a parameter type yet, so we check if the next | 816 // We have not seen a parameter type yet, so we check if the next |
| 820 // identifier could represent a type before parsing it. | 817 // identifier could represent a type before parsing it. |
| 821 Token::Kind follower = LookaheadToken(1); | 818 Token::Kind follower = LookaheadToken(1); |
| 822 // We have an identifier followed by a 'follower' token. | 819 // We have an identifier followed by a 'follower' token. |
| 823 // We either parse a type or assume that no type is specified. | 820 // We either parse a type or assume that no type is specified. |
| 824 if ((follower == Token::kLT) || // Parameterized type. | 821 if ((follower == Token::kLT) || // Parameterized type. |
| 825 (follower == Token::kPERIOD) || // Qualified class name of type. | 822 (follower == Token::kPERIOD) || // Qualified class name of type. |
| 826 (follower == Token::kIDENT) || // Parameter name following a type. | 823 Token::IsIdentifier(follower) || // Parameter name following a type. |
| 827 (follower == Token::kTHIS)) { // Field parameter following a type. | 824 (follower == Token::kTHIS)) { // Field parameter following a type. |
| 828 parameter.type = &AbstractType::ZoneHandle( | 825 parameter.type = &AbstractType::ZoneHandle( |
| 829 ParseType(is_top_level_ ? kCanResolve : kMustResolve)); | 826 ParseType(is_top_level_ ? kCanResolve : kMustResolve)); |
| 830 } else { | 827 } else { |
| 831 parameter.type = &Type::ZoneHandle(Type::DynamicType()); | 828 parameter.type = &Type::ZoneHandle(Type::DynamicType()); |
| 832 } | 829 } |
| 833 } | 830 } |
| 834 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 831 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
| 835 ConsumeToken(); | 832 ConsumeToken(); |
| 836 ExpectToken(Token::kPERIOD); | 833 ExpectToken(Token::kPERIOD); |
| 837 this_seen = true; | 834 this_seen = true; |
| 838 parameter.is_field_initializer = true; | 835 parameter.is_field_initializer = true; |
| 839 } | 836 } |
| 837 |
| 840 // At this point, we must see an identifier for the parameter name. | 838 // At this point, we must see an identifier for the parameter name. |
| 841 if (CurrentToken() != Token::kIDENT) { | |
| 842 ErrorMsg("parameter name expected"); | |
| 843 } | |
| 844 parameter.name = CurrentLiteral(); | |
| 845 parameter.name_pos = token_index_; | 839 parameter.name_pos = token_index_; |
| 846 ConsumeToken(); | 840 parameter.name = ExpectIdentifier("parameter name expected"); |
| 841 |
| 847 if (parameter.is_field_initializer) { | 842 if (parameter.is_field_initializer) { |
| 848 params->has_field_initializer = true; | 843 params->has_field_initializer = true; |
| 849 } | 844 } |
| 850 | 845 |
| 851 if (CurrentToken() == Token::kLPAREN) { | 846 if (CurrentToken() == Token::kLPAREN) { |
| 852 // This parameter is probably a closure. If we saw the keyword 'var' | 847 // This parameter is probably a closure. If we saw the keyword 'var' |
| 853 // or 'final', a closure is not legal here and we ignore the | 848 // or 'final', a closure is not legal here and we ignore the |
| 854 // opening parens. | 849 // opening parens. |
| 855 if (!var_seen && !parameter.is_final) { | 850 if (!var_seen && !parameter.is_final) { |
| 856 // The parsed parameter type is actually the function result type. | 851 // The parsed parameter type is actually the function result type. |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 const Array& fields = Array::Handle(cls.fields()); | 1374 const Array& fields = Array::Handle(cls.fields()); |
| 1380 Field& f = Field::Handle(); | 1375 Field& f = Field::Handle(); |
| 1381 const intptr_t saved_pos = token_index_; | 1376 const intptr_t saved_pos = token_index_; |
| 1382 for (int i = 0; i < fields.Length(); i++) { | 1377 for (int i = 0; i < fields.Length(); i++) { |
| 1383 f ^= fields.At(i); | 1378 f ^= fields.At(i); |
| 1384 if (!f.is_static() && f.has_initializer()) { | 1379 if (!f.is_static() && f.has_initializer()) { |
| 1385 Field& field = Field::ZoneHandle(); | 1380 Field& field = Field::ZoneHandle(); |
| 1386 field ^= fields.At(i); | 1381 field ^= fields.At(i); |
| 1387 intptr_t field_pos = field.token_index(); | 1382 intptr_t field_pos = field.token_index(); |
| 1388 SetPosition(field_pos); | 1383 SetPosition(field_pos); |
| 1389 ASSERT(CurrentToken() == Token::kIDENT); | 1384 ASSERT(IsIdentifier()); |
| 1390 ConsumeToken(); | 1385 ConsumeToken(); |
| 1391 ExpectToken(Token::kASSIGN); | 1386 ExpectToken(Token::kASSIGN); |
| 1392 AstNode* init_expr = ParseConstExpr(); | 1387 AstNode* init_expr = ParseConstExpr(); |
| 1393 ASSERT(init_expr != NULL); | 1388 ASSERT(init_expr != NULL); |
| 1394 FieldInitExpression initializer; | 1389 FieldInitExpression initializer; |
| 1395 initializer.inst_field = &field; | 1390 initializer.inst_field = &field; |
| 1396 initializer.expr = init_expr; | 1391 initializer.expr = init_expr; |
| 1397 initializers->Add(initializer); | 1392 initializers->Add(initializer); |
| 1398 } | 1393 } |
| 1399 } | 1394 } |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1910 ExpectToken(Token::kASSIGN); | 1905 ExpectToken(Token::kASSIGN); |
| 1911 SetAllowFunctionLiterals(false); | 1906 SetAllowFunctionLiterals(false); |
| 1912 SkipExpr(); | 1907 SkipExpr(); |
| 1913 SetAllowFunctionLiterals(true); | 1908 SetAllowFunctionLiterals(true); |
| 1914 } | 1909 } |
| 1915 } while (CurrentToken() == Token::kCOMMA); | 1910 } while (CurrentToken() == Token::kCOMMA); |
| 1916 } | 1911 } |
| 1917 | 1912 |
| 1918 | 1913 |
| 1919 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 1914 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
| 1920 ASSERT(CurrentToken() == Token::kIDENT); | 1915 ASSERT(IsIdentifier()); |
| 1921 if (!is_top_level_) { | 1916 if (!is_top_level_) { |
| 1922 bool is_local_ident = ResolveIdentInLocalScope(token_index_, | 1917 bool is_local_ident = ResolveIdentInLocalScope(token_index_, |
| 1923 *CurrentLiteral(), | 1918 *CurrentLiteral(), |
| 1924 NULL); | 1919 NULL); |
| 1925 qual_ident->ident_pos = token_index_; | 1920 qual_ident->ident_pos = token_index_; |
| 1926 qual_ident->ident = CurrentLiteral(); | 1921 qual_ident->ident = CurrentLiteral(); |
| 1927 qual_ident->lib_prefix = NULL; | 1922 qual_ident->lib_prefix = NULL; |
| 1928 qual_ident->qualifier = NULL; | 1923 qual_ident->qualifier = NULL; |
| 1929 qual_ident->is_local_scope_ident = is_local_ident; | 1924 qual_ident->is_local_scope_ident = is_local_ident; |
| 1930 ConsumeToken(); | 1925 ConsumeToken(); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2265 field->name_pos = this->token_index_; | 2260 field->name_pos = this->token_index_; |
| 2266 field->name = ExpectIdentifier("field name expected"); | 2261 field->name = ExpectIdentifier("field name expected"); |
| 2267 } | 2262 } |
| 2268 ExpectSemicolon(); | 2263 ExpectSemicolon(); |
| 2269 } | 2264 } |
| 2270 | 2265 |
| 2271 | 2266 |
| 2272 void Parser::ParseClassMemberDefinition(ClassDesc* members) { | 2267 void Parser::ParseClassMemberDefinition(ClassDesc* members) { |
| 2273 MemberDesc member; | 2268 MemberDesc member; |
| 2274 current_member_ = &member; | 2269 current_member_ = &member; |
| 2275 if (CurrentToken() == Token::kABSTRACT) { | 2270 if ((CurrentToken() == Token::kABSTRACT) && |
| 2271 (LookaheadToken(1) != Token::kLPAREN)) { |
| 2276 ConsumeToken(); | 2272 ConsumeToken(); |
| 2277 member.has_abstract = true; | 2273 member.has_abstract = true; |
| 2278 } | 2274 } |
| 2279 if (CurrentToken() == Token::kSTATIC) { | 2275 if ((CurrentToken() == Token::kSTATIC) && |
| 2276 (LookaheadToken(1) != Token::kLPAREN)) { |
| 2280 ConsumeToken(); | 2277 ConsumeToken(); |
| 2281 member.has_static = true; | 2278 member.has_static = true; |
| 2282 } | 2279 } |
| 2283 if (CurrentToken() == Token::kCONST) { | 2280 if (CurrentToken() == Token::kCONST) { |
| 2284 ConsumeToken(); | 2281 ConsumeToken(); |
| 2285 member.has_const = true; | 2282 member.has_const = true; |
| 2286 } else if (CurrentToken() == Token::kFINAL) { | 2283 } else if (CurrentToken() == Token::kFINAL) { |
| 2287 ConsumeToken(); | 2284 ConsumeToken(); |
| 2288 member.has_final = true; | 2285 member.has_final = true; |
| 2289 } | 2286 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2317 if ((member.type == NULL) && !member.has_factory) { | 2314 if ((member.type == NULL) && !member.has_factory) { |
| 2318 // We have not seen a member type yet, so we check if the next | 2315 // We have not seen a member type yet, so we check if the next |
| 2319 // identifier could represent a type before parsing it. | 2316 // identifier could represent a type before parsing it. |
| 2320 Token::Kind follower = LookaheadToken(1); | 2317 Token::Kind follower = LookaheadToken(1); |
| 2321 // We have an identifier followed by a 'follower' token. | 2318 // We have an identifier followed by a 'follower' token. |
| 2322 // We either parse a type or assume that no type is specified. | 2319 // We either parse a type or assume that no type is specified. |
| 2323 if ((follower == Token::kLT) || // Parameterized type. | 2320 if ((follower == Token::kLT) || // Parameterized type. |
| 2324 (follower == Token::kGET) || // Getter following a type. | 2321 (follower == Token::kGET) || // Getter following a type. |
| 2325 (follower == Token::kSET) || // Setter following a type. | 2322 (follower == Token::kSET) || // Setter following a type. |
| 2326 (follower == Token::kOPERATOR) || // Operator following a type. | 2323 (follower == Token::kOPERATOR) || // Operator following a type. |
| 2327 (follower == Token::kIDENT) || // Member name following a type. | 2324 (Token::IsIdentifier(follower)) || // Member name following a type. |
| 2328 ((follower == Token::kPERIOD) && // Qualified class name of type, | 2325 ((follower == Token::kPERIOD) && // Qualified class name of type, |
| 2329 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. | 2326 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. |
| 2330 ASSERT(is_top_level_); | 2327 ASSERT(is_top_level_); |
| 2331 member.type = &AbstractType::ZoneHandle(ParseType(kCanResolve)); | 2328 member.type = &AbstractType::ZoneHandle(ParseType(kCanResolve)); |
| 2332 } | 2329 } |
| 2333 } | 2330 } |
| 2334 } | 2331 } |
| 2335 // Optionally parse a (possibly named) constructor name or factory. | 2332 // Optionally parse a (possibly named) constructor name or factory. |
| 2336 if ((CurrentToken() == Token::kIDENT) && | 2333 if (IsIdentifier() && |
| 2337 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 2334 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 2338 member.name = CurrentLiteral(); | 2335 member.name = CurrentLiteral(); |
| 2339 member.name_pos = this->token_index_; | 2336 member.name_pos = this->token_index_; |
| 2340 ConsumeToken(); | 2337 ConsumeToken(); |
| 2341 if (member.has_factory) { | 2338 if (member.has_factory) { |
| 2342 String& qualifier = String::Handle(); | 2339 String& qualifier = String::Handle(); |
| 2343 if (CurrentToken() == Token::kPERIOD) { | 2340 if (CurrentToken() == Token::kPERIOD) { |
| 2344 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 2341 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 2345 lib_prefix = current_class().LookupLibraryPrefix(*member.name); | 2342 lib_prefix = current_class().LookupLibraryPrefix(*member.name); |
| 2346 if (!lib_prefix.IsNull()) { | 2343 if (!lib_prefix.IsNull()) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2396 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2393 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2397 } else { | 2394 } else { |
| 2398 // The type can only be already set in the factory case. | 2395 // The type can only be already set in the factory case. |
| 2399 if (!member.has_factory) { | 2396 if (!member.has_factory) { |
| 2400 ErrorMsg(member.name_pos, "constructor must not specify return type"); | 2397 ErrorMsg(member.name_pos, "constructor must not specify return type"); |
| 2401 } | 2398 } |
| 2402 } | 2399 } |
| 2403 if (CurrentToken() != Token::kLPAREN) { | 2400 if (CurrentToken() != Token::kLPAREN) { |
| 2404 ErrorMsg("left parenthesis expected"); | 2401 ErrorMsg("left parenthesis expected"); |
| 2405 } | 2402 } |
| 2406 } else if (CurrentToken() == Token::kGET) { | 2403 } else if ((CurrentToken() == Token::kGET) && |
| 2404 (LookaheadToken(1) != Token::kLPAREN) && !member.has_var) { |
| 2407 ConsumeToken(); | 2405 ConsumeToken(); |
| 2408 member.kind = RawFunction::kGetterFunction; | 2406 member.kind = RawFunction::kGetterFunction; |
| 2409 member.name_pos = this->token_index_; | 2407 member.name_pos = this->token_index_; |
| 2410 member.name = ExpectIdentifier("identifier expected"); | 2408 member.name = ExpectIdentifier("identifier expected"); |
| 2411 // If the result type was not specified, it will be set to DynamicType. | 2409 // If the result type was not specified, it will be set to DynamicType. |
| 2412 } else if (CurrentToken() == Token::kSET) { | 2410 } else if ((CurrentToken() == Token::kSET) && |
| 2411 (LookaheadToken(1) != Token::kLPAREN) && !member.has_var) { |
| 2413 ConsumeToken(); | 2412 ConsumeToken(); |
| 2414 member.kind = RawFunction::kSetterFunction; | 2413 member.kind = RawFunction::kSetterFunction; |
| 2415 member.name_pos = this->token_index_; | 2414 member.name_pos = this->token_index_; |
| 2416 member.name = ExpectIdentifier("identifier expected"); | 2415 member.name = ExpectIdentifier("identifier expected"); |
| 2417 // The grammar allows a return type, so member.type is not always NULL here. | 2416 // The grammar allows a return type, so member.type is not always NULL here. |
| 2418 // If no return type is specified, the return type of the setter is Dynamic. | 2417 // If no return type is specified, the return type of the setter is Dynamic. |
| 2419 if (member.type == NULL) { | 2418 if (member.type == NULL) { |
| 2420 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2419 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2421 } | 2420 } |
| 2422 } else if (CurrentToken() == Token::kOPERATOR) { | 2421 } else if ((CurrentToken() == Token::kOPERATOR) && |
| 2422 (LookaheadToken(1) != Token::kLPAREN) && !member.has_var) { |
| 2423 ConsumeToken(); | 2423 ConsumeToken(); |
| 2424 if (!Token::CanBeOverloaded(CurrentToken())) { | 2424 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 2425 ErrorMsg("invalid operator overloading"); | 2425 ErrorMsg("invalid operator overloading"); |
| 2426 } | 2426 } |
| 2427 if (member.has_static) { | 2427 if (member.has_static) { |
| 2428 ErrorMsg("operator overloading functions cannot be static"); | 2428 ErrorMsg("operator overloading functions cannot be static"); |
| 2429 } | 2429 } |
| 2430 member.kind = RawFunction::kFunction; | 2430 member.kind = RawFunction::kFunction; |
| 2431 member.name_pos = this->token_index_; | 2431 member.name_pos = this->token_index_; |
| 2432 member.name = | 2432 member.name = |
| 2433 &String::ZoneHandle(String::NewSymbol(Token::Str(CurrentToken()))); | 2433 &String::ZoneHandle(String::NewSymbol(Token::Str(CurrentToken()))); |
| 2434 ConsumeToken(); | 2434 ConsumeToken(); |
| 2435 } else if (CurrentToken() == Token::kIDENT) { | 2435 } else if (IsIdentifier()) { |
| 2436 member.name = CurrentLiteral(); | 2436 member.name = CurrentLiteral(); |
| 2437 member.name_pos = token_index_; | 2437 member.name_pos = token_index_; |
| 2438 ConsumeToken(); | 2438 ConsumeToken(); |
| 2439 } else { | 2439 } else { |
| 2440 ErrorMsg("identifier expected"); | 2440 ErrorMsg("identifier expected"); |
| 2441 } | 2441 } |
| 2442 | 2442 |
| 2443 ASSERT(member.name != NULL); | 2443 ASSERT(member.name != NULL); |
| 2444 if (CurrentToken() == Token::kLPAREN) { | 2444 if (CurrentToken() == Token::kLPAREN) { |
| 2445 if (members->is_interface() && member.has_static) { | 2445 if (members->is_interface() && member.has_static) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2475 current_member_ = NULL; | 2475 current_member_ = NULL; |
| 2476 members->AddMember(member); | 2476 members->AddMember(member); |
| 2477 } | 2477 } |
| 2478 | 2478 |
| 2479 | 2479 |
| 2480 void Parser::ParseClassDefinition(GrowableArray<const Class*>* classes) { | 2480 void Parser::ParseClassDefinition(GrowableArray<const Class*>* classes) { |
| 2481 TRACE_PARSER("ParseClassDefinition"); | 2481 TRACE_PARSER("ParseClassDefinition"); |
| 2482 const intptr_t class_pos = token_index_; | 2482 const intptr_t class_pos = token_index_; |
| 2483 ExpectToken(Token::kCLASS); | 2483 ExpectToken(Token::kCLASS); |
| 2484 const intptr_t classname_pos = token_index_; | 2484 const intptr_t classname_pos = token_index_; |
| 2485 String& class_name = *ExpectIdentifier("class name expected"); | 2485 String& class_name = *ExpectTypeIdentifier("class name expected"); |
| 2486 if (FLAG_trace_parser) { | 2486 if (FLAG_trace_parser) { |
| 2487 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 2487 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 2488 } | 2488 } |
| 2489 Class& cls = Class::ZoneHandle(); | 2489 Class& cls = Class::ZoneHandle(); |
| 2490 Object& obj = Object::Handle(library_.LookupObject(class_name)); | 2490 Object& obj = Object::Handle(library_.LookupObject(class_name)); |
| 2491 if (obj.IsNull()) { | 2491 if (obj.IsNull()) { |
| 2492 cls = Class::New(class_name, script_); | 2492 cls = Class::New(class_name, script_); |
| 2493 library_.AddClass(cls); | 2493 library_.AddClass(cls); |
| 2494 } else { | 2494 } else { |
| 2495 if (!obj.IsClass()) { | 2495 if (!obj.IsClass()) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2617 } | 2617 } |
| 2618 } | 2618 } |
| 2619 } | 2619 } |
| 2620 | 2620 |
| 2621 | 2621 |
| 2622 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 2622 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 2623 // We need this lookahead to distinguish between the optional return type | 2623 // We need this lookahead to distinguish between the optional return type |
| 2624 // and the alias name of a function type alias. | 2624 // and the alias name of a function type alias. |
| 2625 // Token position remains unchanged. | 2625 // Token position remains unchanged. |
| 2626 bool Parser::IsFunctionTypeAliasName() { | 2626 bool Parser::IsFunctionTypeAliasName() { |
| 2627 if ((CurrentToken() == Token::kIDENT) && | 2627 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 2628 (LookaheadToken(1) == Token::kLPAREN)) { | |
| 2629 return true; | 2628 return true; |
| 2630 } | 2629 } |
| 2631 const intptr_t saved_pos = token_index_; | 2630 const intptr_t saved_pos = token_index_; |
| 2632 bool is_alias_name = false; | 2631 bool is_alias_name = false; |
| 2633 if ((CurrentToken() == Token::kIDENT) && | 2632 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 2634 (LookaheadToken(1) == Token::kLT)) { | |
| 2635 ConsumeToken(); | 2633 ConsumeToken(); |
| 2636 if (IsTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 2634 if (IsTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
| 2637 is_alias_name = true; | 2635 is_alias_name = true; |
| 2638 } | 2636 } |
| 2639 } | 2637 } |
| 2640 SetPosition(saved_pos); | 2638 SetPosition(saved_pos); |
| 2641 return is_alias_name; | 2639 return is_alias_name; |
| 2642 } | 2640 } |
| 2643 | 2641 |
| 2644 | 2642 |
| 2645 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { | 2643 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { |
| 2646 TRACE_PARSER("ParseFunctionTypeAlias"); | 2644 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 2647 ExpectToken(Token::kTYPEDEF); | 2645 ExpectToken(Token::kTYPEDEF); |
| 2648 | 2646 |
| 2649 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 2647 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 2650 const intptr_t result_type_pos = token_index_; | 2648 const intptr_t result_type_pos = token_index_; |
| 2651 if (CurrentToken() == Token::kVOID) { | 2649 if (CurrentToken() == Token::kVOID) { |
| 2652 ConsumeToken(); | 2650 ConsumeToken(); |
| 2653 result_type = Type::VoidType(); | 2651 result_type = Type::VoidType(); |
| 2654 } else if (!IsFunctionTypeAliasName()) { | 2652 } else if (!IsFunctionTypeAliasName()) { |
| 2655 result_type = ParseType(kDoNotResolve); // No owner class yet. | 2653 result_type = ParseType(kDoNotResolve); // No owner class yet. |
| 2656 } | 2654 } |
| 2657 | 2655 |
| 2658 if (CurrentToken() != Token::kIDENT) { | |
| 2659 ErrorMsg("function alias name expected"); | |
| 2660 } | |
| 2661 const intptr_t alias_name_pos = token_index_; | 2656 const intptr_t alias_name_pos = token_index_; |
| 2662 const String* alias_name = CurrentLiteral(); | 2657 const String* alias_name = |
| 2663 ConsumeToken(); | 2658 ExpectTypeIdentifier("function alias name expected"); |
| 2664 | 2659 |
| 2665 // Allocate an interface to hold the type parameters and their 'extends' | 2660 // Allocate an interface to hold the type parameters and their 'extends' |
| 2666 // constraints. Make it the owner of the function type descriptor. | 2661 // constraints. Make it the owner of the function type descriptor. |
| 2667 const Class& alias_owner = Class::Handle( | 2662 const Class& alias_owner = Class::Handle( |
| 2668 Class::New(String::Handle(String::NewSymbol(":alias_owner")), | 2663 Class::New(String::Handle(String::NewSymbol(":alias_owner")), |
| 2669 Script::Handle())); | 2664 Script::Handle())); |
| 2670 alias_owner.set_is_interface(); | 2665 alias_owner.set_is_interface(); |
| 2671 set_current_class(alias_owner); | 2666 set_current_class(alias_owner); |
| 2672 ParseTypeParameters(alias_owner); | 2667 ParseTypeParameters(alias_owner); |
| 2673 if (CurrentToken() != Token::kLPAREN) { | 2668 if (CurrentToken() != Token::kLPAREN) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2730 ExpectSemicolon(); | 2725 ExpectSemicolon(); |
| 2731 classes->Add(&function_type_alias); | 2726 classes->Add(&function_type_alias); |
| 2732 } | 2727 } |
| 2733 | 2728 |
| 2734 | 2729 |
| 2735 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { | 2730 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { |
| 2736 TRACE_PARSER("ParseInterfaceDefinition"); | 2731 TRACE_PARSER("ParseInterfaceDefinition"); |
| 2737 const intptr_t interface_pos = token_index_; | 2732 const intptr_t interface_pos = token_index_; |
| 2738 ExpectToken(Token::kINTERFACE); | 2733 ExpectToken(Token::kINTERFACE); |
| 2739 const intptr_t interfacename_pos = token_index_; | 2734 const intptr_t interfacename_pos = token_index_; |
| 2740 String& interface_name = *ExpectIdentifier("interface name expected"); | 2735 String& interface_name = *ExpectTypeIdentifier("interface name expected"); |
| 2741 if (FLAG_trace_parser) { | 2736 if (FLAG_trace_parser) { |
| 2742 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | 2737 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); |
| 2743 } | 2738 } |
| 2744 Class& interface = Class::ZoneHandle(); | 2739 Class& interface = Class::ZoneHandle(); |
| 2745 Object& obj = Object::Handle(library_.LookupObject(interface_name)); | 2740 Object& obj = Object::Handle(library_.LookupObject(interface_name)); |
| 2746 if (obj.IsNull()) { | 2741 if (obj.IsNull()) { |
| 2747 interface = Class::NewInterface(interface_name, script_); | 2742 interface = Class::NewInterface(interface_name, script_); |
| 2748 library_.AddClass(interface); | 2743 library_.AddClass(interface); |
| 2749 } else { | 2744 } else { |
| 2750 if (!obj.IsClass()) { | 2745 if (!obj.IsClass()) { |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3273 ConsumeToken(); | 3268 ConsumeToken(); |
| 3274 ExpectToken(Token::kLPAREN); | 3269 ExpectToken(Token::kLPAREN); |
| 3275 if (CurrentToken() != Token::kSTRING) { | 3270 if (CurrentToken() != Token::kSTRING) { |
| 3276 ErrorMsg("library url expected"); | 3271 ErrorMsg("library url expected"); |
| 3277 } | 3272 } |
| 3278 const String& url = *CurrentLiteral(); | 3273 const String& url = *CurrentLiteral(); |
| 3279 ConsumeToken(); | 3274 ConsumeToken(); |
| 3280 String& prefix = String::Handle(); | 3275 String& prefix = String::Handle(); |
| 3281 if (CurrentToken() == Token::kCOMMA) { | 3276 if (CurrentToken() == Token::kCOMMA) { |
| 3282 ConsumeToken(); | 3277 ConsumeToken(); |
| 3283 const String& kPrefix = String::Handle(String::NewSymbol("prefix")); | 3278 if (!IsLiteral("prefix")) { |
| 3284 if ((CurrentToken() != Token::kIDENT) || | |
| 3285 !kPrefix.Equals(*CurrentLiteral())) { | |
| 3286 ErrorMsg("prefix: expected"); | 3279 ErrorMsg("prefix: expected"); |
| 3287 } | 3280 } |
| 3288 ConsumeToken(); | 3281 ConsumeToken(); |
| 3289 ExpectToken(Token::kCOLON); | 3282 ExpectToken(Token::kCOLON); |
| 3290 if (CurrentToken() != Token::kSTRING) { | 3283 if (CurrentToken() != Token::kSTRING) { |
| 3291 ErrorMsg("prefix expected"); | 3284 ErrorMsg("prefix expected"); |
| 3292 } | 3285 } |
| 3293 prefix = CurrentLiteral()->raw(); | 3286 prefix = CurrentLiteral()->raw(); |
| 3294 // TODO(asiva): Need to also check that prefix is not a reserved keyword. | 3287 // TODO(asiva): Need to also check that prefix is not a reserved keyword. |
| 3295 if (!Scanner::IsIdent(prefix)) { | 3288 if (!Scanner::IsIdent(prefix)) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3374 toplevel_class.set_library(library_); | 3367 toplevel_class.set_library(library_); |
| 3375 | 3368 |
| 3376 if (is_library_source()) { | 3369 if (is_library_source()) { |
| 3377 ParseLibraryDefinition(); | 3370 ParseLibraryDefinition(); |
| 3378 } | 3371 } |
| 3379 | 3372 |
| 3380 while (true) { | 3373 while (true) { |
| 3381 set_current_class(Class::Handle()); // No current class. | 3374 set_current_class(Class::Handle()); // No current class. |
| 3382 if (CurrentToken() == Token::kCLASS) { | 3375 if (CurrentToken() == Token::kCLASS) { |
| 3383 ParseClassDefinition(&classes); | 3376 ParseClassDefinition(&classes); |
| 3384 } else if (CurrentToken() == Token::kTYPEDEF) { | 3377 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 3378 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3385 ParseFunctionTypeAlias(&classes); | 3379 ParseFunctionTypeAlias(&classes); |
| 3386 } else if (CurrentToken() == Token::kINTERFACE) { | 3380 } else if (CurrentToken() == Token::kINTERFACE) { |
| 3387 ParseInterfaceDefinition(&classes); | 3381 ParseInterfaceDefinition(&classes); |
| 3388 } else if (IsVariableDeclaration()) { | 3382 } else if (IsVariableDeclaration()) { |
| 3389 set_current_class(toplevel_class); | 3383 set_current_class(toplevel_class); |
| 3390 ParseTopLevelVariable(&top_level); | 3384 ParseTopLevelVariable(&top_level); |
| 3391 } else if (IsTopLevelFunction()) { | 3385 } else if (IsTopLevelFunction()) { |
| 3392 set_current_class(toplevel_class); | 3386 set_current_class(toplevel_class); |
| 3393 ParseTopLevelFunction(&top_level); | 3387 ParseTopLevelFunction(&top_level); |
| 3394 } else if (IsTopLevelAccessor()) { | 3388 } else if (IsTopLevelAccessor()) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3611 AstNode* object, | 3605 AstNode* object, |
| 3612 const String& name) { | 3606 const String& name) { |
| 3613 return new InstanceGetterNode(token_index_, object, name); | 3607 return new InstanceGetterNode(token_index_, object, name); |
| 3614 } | 3608 } |
| 3615 | 3609 |
| 3616 | 3610 |
| 3617 // Returns ast nodes of the variable initialization. | 3611 // Returns ast nodes of the variable initialization. |
| 3618 AstNode* Parser::ParseVariableDeclaration( | 3612 AstNode* Parser::ParseVariableDeclaration( |
| 3619 const AbstractType& type, bool is_final) { | 3613 const AbstractType& type, bool is_final) { |
| 3620 TRACE_PARSER("ParseVariableDeclaration"); | 3614 TRACE_PARSER("ParseVariableDeclaration"); |
| 3621 ASSERT(CurrentToken() == Token::kIDENT); | 3615 ASSERT(IsIdentifier()); |
| 3622 const intptr_t ident_pos = token_index_; | 3616 const intptr_t ident_pos = token_index_; |
| 3623 LocalVariable* variable = | 3617 LocalVariable* variable = |
| 3624 new LocalVariable(ident_pos, *CurrentLiteral(), type); | 3618 new LocalVariable(ident_pos, *CurrentLiteral(), type); |
| 3625 ASSERT(current_block_ != NULL); | 3619 ASSERT(current_block_ != NULL); |
| 3626 ASSERT(current_block_->scope != NULL); | 3620 ASSERT(current_block_->scope != NULL); |
| 3627 ConsumeToken(); // Variable identifier. | 3621 ConsumeToken(); // Variable identifier. |
| 3628 AstNode* initialization = NULL; | 3622 AstNode* initialization = NULL; |
| 3629 if (CurrentToken() == Token::kASSIGN) { | 3623 if (CurrentToken() == Token::kASSIGN) { |
| 3630 // Variable initialization. | 3624 // Variable initialization. |
| 3631 const intptr_t assign_pos = token_index_; | 3625 const intptr_t assign_pos = token_index_; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3664 return Type::DynamicType(); | 3658 return Type::DynamicType(); |
| 3665 } | 3659 } |
| 3666 if (CurrentToken() == Token::kFINAL) { | 3660 if (CurrentToken() == Token::kFINAL) { |
| 3667 ConsumeToken(); | 3661 ConsumeToken(); |
| 3668 type_specification = kIsOptional; | 3662 type_specification = kIsOptional; |
| 3669 } | 3663 } |
| 3670 if (CurrentToken() != Token::kIDENT) { | 3664 if (CurrentToken() != Token::kIDENT) { |
| 3671 if (type_specification == kIsOptional) { | 3665 if (type_specification == kIsOptional) { |
| 3672 return Type::DynamicType(); | 3666 return Type::DynamicType(); |
| 3673 } else { | 3667 } else { |
| 3674 ErrorMsg("identifier expected"); | 3668 ErrorMsg("type name expected"); |
| 3675 } | 3669 } |
| 3676 } | 3670 } |
| 3677 if (type_specification == kIsOptional) { | 3671 if (type_specification == kIsOptional) { |
| 3678 Token::Kind follower = LookaheadToken(1); | 3672 Token::Kind follower = LookaheadToken(1); |
| 3679 // We have an identifier followed by a 'follower' token. | 3673 // We have an identifier followed by a 'follower' token. |
| 3680 // We either parse a type or return now. | 3674 // We either parse a type or return now. |
| 3681 if ((follower != Token::kLT) && // Parameterized type. | 3675 if ((follower != Token::kLT) && // Parameterized type. |
| 3682 (follower != Token::kPERIOD) && // Qualified class name of type. | 3676 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 3683 (follower != Token::kIDENT) && // Variable name following a type. | 3677 !Token::IsIdentifier(follower) && // Variable name following a type. |
| 3684 (follower != Token::kTHIS)) { // Field parameter following a type. | 3678 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 3685 return Type::DynamicType(); | 3679 return Type::DynamicType(); |
| 3686 } | 3680 } |
| 3687 } | 3681 } |
| 3688 return ParseType(type_resolution); | 3682 return ParseType(type_resolution); |
| 3689 } | 3683 } |
| 3690 | 3684 |
| 3691 | 3685 |
| 3692 // Returns ast nodes of the variable initialization. Variables without an | 3686 // Returns ast nodes of the variable initialization. Variables without an |
| 3693 // explicit initializer are initialized to null. If several variables are | 3687 // explicit initializer are initialized to null. If several variables are |
| 3694 // declared, the individual initializers are collected in a sequence node. | 3688 // declared, the individual initializers are collected in a sequence node. |
| 3695 AstNode* Parser::ParseVariableDeclarationList() { | 3689 AstNode* Parser::ParseVariableDeclarationList() { |
| 3696 TRACE_PARSER("ParseVariableDeclarationList"); | 3690 TRACE_PARSER("ParseVariableDeclarationList"); |
| 3697 bool is_final = (CurrentToken() == Token::kFINAL); | 3691 bool is_final = (CurrentToken() == Token::kFINAL); |
| 3698 const AbstractType& type = AbstractType::ZoneHandle( | 3692 const AbstractType& type = AbstractType::ZoneHandle( |
| 3699 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 3693 ParseFinalVarOrType(kIsMandatory, kMustResolve)); |
| 3700 if (CurrentToken() != Token::kIDENT) { | 3694 if (!IsIdentifier()) { |
| 3701 ErrorMsg("identifier expected"); | 3695 ErrorMsg("identifier expected"); |
| 3702 } | 3696 } |
| 3703 | 3697 |
| 3704 AstNode* initializers = ParseVariableDeclaration(type, is_final); | 3698 AstNode* initializers = ParseVariableDeclaration(type, is_final); |
| 3705 ASSERT(initializers != NULL); | 3699 ASSERT(initializers != NULL); |
| 3706 while (CurrentToken() == Token::kCOMMA) { | 3700 while (CurrentToken() == Token::kCOMMA) { |
| 3707 ConsumeToken(); | 3701 ConsumeToken(); |
| 3708 if (CurrentToken() != Token::kIDENT) { | 3702 if (!IsIdentifier()) { |
| 3709 ErrorMsg("identifier expected after comma"); | 3703 ErrorMsg("identifier expected after comma"); |
| 3710 } | 3704 } |
| 3711 // We have a second initializer. Allocate a sequence node now. | 3705 // We have a second initializer. Allocate a sequence node now. |
| 3712 // The sequence does not own the current scope. Set its own scope to NULL. | 3706 // The sequence does not own the current scope. Set its own scope to NULL. |
| 3713 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_index(), | 3707 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_index(), |
| 3714 initializers, | 3708 initializers, |
| 3715 NULL); | 3709 NULL); |
| 3716 sequence->Add(ParseVariableDeclaration(type, is_final)); | 3710 sequence->Add(ParseVariableDeclaration(type, is_final)); |
| 3717 initializers = sequence; | 3711 initializers = sequence; |
| 3718 } | 3712 } |
| 3719 return initializers; | 3713 return initializers; |
| 3720 } | 3714 } |
| 3721 | 3715 |
| 3722 | 3716 |
| 3723 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 3717 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 3724 TRACE_PARSER("ParseFunctionStatement"); | 3718 TRACE_PARSER("ParseFunctionStatement"); |
| 3725 AbstractType& result_type = AbstractType::Handle(); | 3719 AbstractType& result_type = AbstractType::Handle(); |
| 3726 const String* variable_name = NULL; | 3720 const String* variable_name = NULL; |
| 3727 const String* function_name = NULL; | 3721 const String* function_name = NULL; |
| 3728 | 3722 |
| 3729 result_type = Type::DynamicType(); | 3723 result_type = Type::DynamicType(); |
| 3730 if (CurrentToken() == Token::kVOID) { | 3724 if (CurrentToken() == Token::kVOID) { |
| 3731 ConsumeToken(); | 3725 ConsumeToken(); |
| 3732 result_type = Type::VoidType(); | 3726 result_type = Type::VoidType(); |
| 3733 } else if ((CurrentToken() == Token::kIDENT) && | 3727 } else if ((CurrentToken() == Token::kIDENT) && |
| 3734 (LookaheadToken(1) != Token::kLPAREN)) { | 3728 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3735 result_type = ParseType(kMustResolve); | 3729 result_type = ParseType(kMustResolve); |
| 3736 } | 3730 } |
| 3737 const intptr_t ident_pos = token_index_; | 3731 const intptr_t ident_pos = token_index_; |
| 3738 if (CurrentToken() == Token::kIDENT) { | 3732 if (IsIdentifier()) { |
| 3739 variable_name = CurrentLiteral(); | 3733 variable_name = CurrentLiteral(); |
| 3740 function_name = variable_name; | 3734 function_name = variable_name; |
| 3741 ConsumeToken(); | 3735 ConsumeToken(); |
| 3742 } else { | 3736 } else { |
| 3743 if (!is_literal) { | 3737 if (!is_literal) { |
| 3744 ErrorMsg("function name expected"); | 3738 ErrorMsg("function name expected"); |
| 3745 } | 3739 } |
| 3746 const String& anonymous_function_name = | 3740 const String& anonymous_function_name = |
| 3747 String::ZoneHandle(String::NewSymbol("function")); | 3741 String::ZoneHandle(String::NewSymbol("function")); |
| 3748 function_name = &anonymous_function_name; | 3742 function_name = &anonymous_function_name; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3919 ConsumeToken(); | 3913 ConsumeToken(); |
| 3920 } while (nesting_level > 0); | 3914 } while (nesting_level > 0); |
| 3921 if (nesting_level < 0) { | 3915 if (nesting_level < 0) { |
| 3922 return false; | 3916 return false; |
| 3923 } | 3917 } |
| 3924 } | 3918 } |
| 3925 return true; | 3919 return true; |
| 3926 } | 3920 } |
| 3927 | 3921 |
| 3928 | 3922 |
| 3923 // Returns true if the current token is kIDENT or a pseudo-keyword. |
| 3924 bool Parser::IsIdentifier() { |
| 3925 return Token::IsIdentifier(CurrentToken()); |
| 3926 } |
| 3927 |
| 3928 |
| 3929 // Returns true if the next tokens can be parsed as a type with optional | 3929 // Returns true if the next tokens can be parsed as a type with optional |
| 3930 // type parameters. Current token position is not restored. | 3930 // type parameters. Current token position is not restored. |
| 3931 bool Parser::IsOptionalType() { | 3931 bool Parser::IsOptionalType() { |
| 3932 if (CurrentToken() == Token::kIDENT) { | 3932 if (CurrentToken() == Token::kIDENT) { |
| 3933 QualIdent type_name; | 3933 QualIdent type_name; |
| 3934 ParseQualIdent(&type_name); | 3934 ParseQualIdent(&type_name); |
| 3935 // Check if the type_name has been defined as a variable in a local scope, | 3935 // Check if the type_name has been defined as a variable in a local scope, |
| 3936 // hiding the type. | 3936 // hiding the type. |
| 3937 if (type_name.is_local_scope_ident) { | 3937 if (type_name.is_local_scope_ident) { |
| 3938 return false; | 3938 return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3962 // Look ahead to detect whether the next tokens should be parsed as | 3962 // Look ahead to detect whether the next tokens should be parsed as |
| 3963 // a variable declaration. Returns true if we detect the token pattern: | 3963 // a variable declaration. Returns true if we detect the token pattern: |
| 3964 // ('var' | 'final' | type ident (';' | '=' | ',')) | 3964 // ('var' | 'final' | type ident (';' | '=' | ',')) |
| 3965 // Token position remains unchanged. | 3965 // Token position remains unchanged. |
| 3966 bool Parser::IsVariableDeclaration() { | 3966 bool Parser::IsVariableDeclaration() { |
| 3967 if ((CurrentToken() == Token::kVAR) || | 3967 if ((CurrentToken() == Token::kVAR) || |
| 3968 (CurrentToken() == Token::kFINAL)) { | 3968 (CurrentToken() == Token::kFINAL)) { |
| 3969 return true; | 3969 return true; |
| 3970 } | 3970 } |
| 3971 if (CurrentToken() != Token::kIDENT) { | 3971 if (CurrentToken() != Token::kIDENT) { |
| 3972 // Not a legal type identifier. |
| 3972 return false; | 3973 return false; |
| 3973 } | 3974 } |
| 3974 const intptr_t saved_pos = token_index_; | 3975 const intptr_t saved_pos = token_index_; |
| 3975 bool is_var_decl = false; | 3976 bool is_var_decl = false; |
| 3976 if (IsOptionalType()) { | 3977 if (IsOptionalType()) { |
| 3977 if (CurrentToken() == Token::kIDENT) { | 3978 if (IsIdentifier()) { |
| 3978 ConsumeToken(); | 3979 ConsumeToken(); |
| 3979 if ((CurrentToken() == Token::kSEMICOLON) || | 3980 if ((CurrentToken() == Token::kSEMICOLON) || |
| 3980 (CurrentToken() == Token::kCOMMA) || | 3981 (CurrentToken() == Token::kCOMMA) || |
| 3981 (CurrentToken() == Token::kASSIGN)) { | 3982 (CurrentToken() == Token::kASSIGN)) { |
| 3982 is_var_decl = true; | 3983 is_var_decl = true; |
| 3983 } | 3984 } |
| 3984 } | 3985 } |
| 3985 } | 3986 } |
| 3986 SetPosition(saved_pos); | 3987 SetPosition(saved_pos); |
| 3987 return is_var_decl; | 3988 return is_var_decl; |
| 3988 } | 3989 } |
| 3989 | 3990 |
| 3990 | 3991 |
| 3991 bool Parser::IsFunctionDeclaration() { | 3992 bool Parser::IsFunctionDeclaration() { |
| 3992 // A function declaration is like a function literal but it must have | 3993 // A function declaration is like a function literal but it must have |
| 3993 // a name. | 3994 // a name. |
| 3994 return (CurrentToken() != Token::kLPAREN) && IsFunctionLiteral(); | 3995 return (CurrentToken() != Token::kLPAREN) && IsFunctionLiteral(); |
| 3995 } | 3996 } |
| 3996 | 3997 |
| 3997 | 3998 |
| 3998 bool Parser::IsTopLevelFunction() { | 3999 bool Parser::IsTopLevelFunction() { |
| 3999 // Top-level function declarations can omit the return type. Check for | 4000 // Top-level function declarations can omit the return type. Check for |
| 4000 // that case separately. | 4001 // that case separately. |
| 4001 return ((CurrentToken() == Token::kIDENT) && | 4002 return (IsIdentifier() && |
| 4002 (LookaheadToken(1) == Token::kLPAREN)) || | 4003 (LookaheadToken(1) == Token::kLPAREN)) || IsFunctionDeclaration(); |
| 4003 IsFunctionDeclaration(); | |
| 4004 } | 4004 } |
| 4005 | 4005 |
| 4006 | 4006 |
| 4007 bool Parser::IsTopLevelAccessor() { | 4007 bool Parser::IsTopLevelAccessor() { |
| 4008 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4008 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4009 return true; | 4009 return true; |
| 4010 } | 4010 } |
| 4011 const intptr_t saved_pos = token_index_; | 4011 const intptr_t saved_pos = token_index_; |
| 4012 if (IsReturnType()) { | 4012 if (IsReturnType()) { |
| 4013 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4013 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4014 if (LookaheadToken(1) == Token::kIDENT) { // Accessor name. | 4014 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 4015 SetPosition(saved_pos); | 4015 SetPosition(saved_pos); |
| 4016 return true; | 4016 return true; |
| 4017 } | 4017 } |
| 4018 } | 4018 } |
| 4019 } | 4019 } |
| 4020 SetPosition(saved_pos); | 4020 SetPosition(saved_pos); |
| 4021 return false; | 4021 return false; |
| 4022 } | 4022 } |
| 4023 | 4023 |
| 4024 | 4024 |
| 4025 bool Parser::IsFunctionLiteral() { | 4025 bool Parser::IsFunctionLiteral() { |
| 4026 if (!allow_function_literals_) { | 4026 if (!allow_function_literals_) { |
| 4027 return false; | 4027 return false; |
| 4028 } | 4028 } |
| 4029 const intptr_t saved_pos = token_index_; | 4029 const intptr_t saved_pos = token_index_; |
| 4030 bool is_function_literal = false; | 4030 bool is_function_literal = false; |
| 4031 if ((CurrentToken() == Token::kIDENT) && | 4031 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4032 (LookaheadToken(1) == Token::kLPAREN)) { | |
| 4033 ConsumeToken(); // Consume function identifier. | 4032 ConsumeToken(); // Consume function identifier. |
| 4034 } else if (IsReturnType()) { | 4033 } else if (IsReturnType()) { |
| 4035 if (CurrentToken() != Token::kIDENT) { | 4034 if (!IsIdentifier()) { |
| 4036 SetPosition(saved_pos); | 4035 SetPosition(saved_pos); |
| 4037 return false; | 4036 return false; |
| 4038 } | 4037 } |
| 4039 ConsumeToken(); // Comsume function identifier. | 4038 ConsumeToken(); // Comsume function identifier. |
| 4040 } | 4039 } |
| 4041 if (CurrentToken() == Token::kLPAREN) { | 4040 if (CurrentToken() == Token::kLPAREN) { |
| 4042 SkipToMatchingParenthesis(); | 4041 SkipToMatchingParenthesis(); |
| 4043 if ((CurrentToken() == Token::kLBRACE) || | 4042 if ((CurrentToken() == Token::kLBRACE) || |
| 4044 (CurrentToken() == Token::kARROW)) { | 4043 (CurrentToken() == Token::kARROW)) { |
| 4045 is_function_literal = true; | 4044 is_function_literal = true; |
| 4046 } | 4045 } |
| 4047 } | 4046 } |
| 4048 SetPosition(saved_pos); | 4047 SetPosition(saved_pos); |
| 4049 return is_function_literal; | 4048 return is_function_literal; |
| 4050 } | 4049 } |
| 4051 | 4050 |
| 4052 | 4051 |
| 4053 // Current token position is the token after the opening ( of the for | 4052 // Current token position is the token after the opening ( of the for |
| 4054 // statement. Returns true if we recognize a for ( .. in expr) | 4053 // statement. Returns true if we recognize a for ( .. in expr) |
| 4055 // statement. | 4054 // statement. |
| 4056 bool Parser::IsForInStatement() { | 4055 bool Parser::IsForInStatement() { |
| 4057 const intptr_t saved_pos = token_index_; | 4056 const intptr_t saved_pos = token_index_; |
| 4058 bool result = false; | 4057 bool result = false; |
| 4059 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { | 4058 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { |
| 4060 ConsumeToken(); | 4059 ConsumeToken(); |
| 4061 } | 4060 } |
| 4062 if (CurrentToken() == Token::kIDENT) { | 4061 if (IsIdentifier()) { |
| 4063 if (LookaheadToken(1) == Token::kIN) { | 4062 if (LookaheadToken(1) == Token::kIN) { |
| 4064 result = true; | 4063 result = true; |
| 4065 } else if (IsOptionalType()) { | 4064 } else if (IsOptionalType()) { |
| 4066 if (CurrentToken() == Token::kIDENT) { | 4065 if (IsIdentifier()) { |
| 4067 ConsumeToken(); | 4066 ConsumeToken(); |
| 4068 } | 4067 } |
| 4069 result = (CurrentToken() == Token::kIN); | 4068 result = (CurrentToken() == Token::kIN); |
| 4070 } | 4069 } |
| 4071 } | 4070 } |
| 4072 SetPosition(saved_pos); | 4071 SetPosition(saved_pos); |
| 4073 return result; | 4072 return result; |
| 4074 } | 4073 } |
| 4075 | 4074 |
| 4076 | 4075 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4207 ExpectToken(Token::kCOLON); | 4206 ExpectToken(Token::kCOLON); |
| 4208 } | 4207 } |
| 4209 | 4208 |
| 4210 OpenBlock(); | 4209 OpenBlock(); |
| 4211 bool abrupt_completing_seen = false; | 4210 bool abrupt_completing_seen = false; |
| 4212 while (true) { | 4211 while (true) { |
| 4213 // Check whether the next statement still belongs to the current case | 4212 // Check whether the next statement still belongs to the current case |
| 4214 // clause. If we see 'case' or 'default', optionally preceeded by | 4213 // clause. If we see 'case' or 'default', optionally preceeded by |
| 4215 // a label, or closing brace, we stop parsing statements. | 4214 // a label, or closing brace, we stop parsing statements. |
| 4216 Token::Kind next_token; | 4215 Token::Kind next_token; |
| 4217 if (CurrentToken() == Token::kIDENT && | 4216 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 4218 LookaheadToken(1) == Token::kCOLON) { | |
| 4219 next_token = LookaheadToken(2); | 4217 next_token = LookaheadToken(2); |
| 4220 } else { | 4218 } else { |
| 4221 next_token = CurrentToken(); | 4219 next_token = CurrentToken(); |
| 4222 } | 4220 } |
| 4223 if (next_token == Token::kRBRACE) { | 4221 if (next_token == Token::kRBRACE) { |
| 4224 // End of switch statement. | 4222 // End of switch statement. |
| 4225 break; | 4223 break; |
| 4226 } | 4224 } |
| 4227 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 4225 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
| 4228 // End of this case clause. If there is a possible fall-through to | 4226 // End of this case clause. If there is a possible fall-through to |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4281 current_block_->scope->AddVariable(temp_variable); | 4279 current_block_->scope->AddVariable(temp_variable); |
| 4282 AstNode* save_switch_expr = | 4280 AstNode* save_switch_expr = |
| 4283 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 4281 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
| 4284 current_block_->statements->Add(save_switch_expr); | 4282 current_block_->statements->Add(save_switch_expr); |
| 4285 | 4283 |
| 4286 // Parse case clauses | 4284 // Parse case clauses |
| 4287 bool default_seen = false; | 4285 bool default_seen = false; |
| 4288 while (true) { | 4286 while (true) { |
| 4289 // Check for statement label | 4287 // Check for statement label |
| 4290 SourceLabel* case_label = NULL; | 4288 SourceLabel* case_label = NULL; |
| 4291 if (CurrentToken() == Token::kIDENT && | 4289 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 4292 LookaheadToken(1) == Token::kCOLON) { | |
| 4293 // Case statements start with a label. | 4290 // Case statements start with a label. |
| 4294 String* label_name = CurrentLiteral(); | 4291 String* label_name = CurrentLiteral(); |
| 4295 const intptr_t label_pos = token_index_; | 4292 const intptr_t label_pos = token_index_; |
| 4296 ConsumeToken(); // Consume label identifier. | 4293 ConsumeToken(); // Consume label identifier. |
| 4297 ConsumeToken(); // Consume colon. | 4294 ConsumeToken(); // Consume colon. |
| 4298 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 4295 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 4299 if (case_label == NULL) { | 4296 if (case_label == NULL) { |
| 4300 // Label does not exist yet. Add it to scope of switch statement. | 4297 // Label does not exist yet. Add it to scope of switch statement. |
| 4301 case_label = | 4298 case_label = |
| 4302 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); | 4299 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4641 }; | 4638 }; |
| 4642 | 4639 |
| 4643 | 4640 |
| 4644 // Parse the parameter specified in the catch clause. | 4641 // Parse the parameter specified in the catch clause. |
| 4645 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { | 4642 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { |
| 4646 TRACE_PARSER("ParseCatchParameter"); | 4643 TRACE_PARSER("ParseCatchParameter"); |
| 4647 ASSERT(catch_param != NULL); | 4644 ASSERT(catch_param != NULL); |
| 4648 catch_param->is_final = (CurrentToken() == Token::kFINAL); | 4645 catch_param->is_final = (CurrentToken() == Token::kFINAL); |
| 4649 catch_param->type = &AbstractType::ZoneHandle( | 4646 catch_param->type = &AbstractType::ZoneHandle( |
| 4650 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4647 ParseFinalVarOrType(kIsMandatory, kMustResolve)); |
| 4651 if (CurrentToken() != Token::kIDENT) { | |
| 4652 ErrorMsg("identifier expected"); | |
| 4653 } | |
| 4654 catch_param->token_index = token_index_; | 4648 catch_param->token_index = token_index_; |
| 4655 catch_param->var = CurrentLiteral(); | 4649 catch_param->var = ExpectIdentifier("identifier expected"); |
| 4656 ConsumeToken(); | |
| 4657 } | 4650 } |
| 4658 | 4651 |
| 4659 | 4652 |
| 4660 // Populate local scope of the catch block with the catch parameters. | 4653 // Populate local scope of the catch block with the catch parameters. |
| 4661 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 4654 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
| 4662 const CatchParamDesc& stack_trace_param, | 4655 const CatchParamDesc& stack_trace_param, |
| 4663 LocalScope* scope) { | 4656 LocalScope* scope) { |
| 4664 ASSERT(exception_param.var != NULL); | 4657 ASSERT(exception_param.var != NULL); |
| 4665 LocalVariable* var = new LocalVariable(exception_param.token_index, | 4658 LocalVariable* var = new LocalVariable(exception_param.token_index, |
| 4666 *(exception_param.var), | 4659 *(exception_param.var), |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4981 return try_catch_node; | 4974 return try_catch_node; |
| 4982 } | 4975 } |
| 4983 | 4976 |
| 4984 | 4977 |
| 4985 AstNode* Parser::ParseJump(String* label_name) { | 4978 AstNode* Parser::ParseJump(String* label_name) { |
| 4986 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 4979 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 4987 Token::Kind jump_kind = CurrentToken(); | 4980 Token::Kind jump_kind = CurrentToken(); |
| 4988 const intptr_t jump_pos = token_index_; | 4981 const intptr_t jump_pos = token_index_; |
| 4989 SourceLabel* target = NULL; | 4982 SourceLabel* target = NULL; |
| 4990 ConsumeToken(); | 4983 ConsumeToken(); |
| 4991 if (CurrentToken() == Token::kIDENT) { | 4984 if (IsIdentifier()) { |
| 4992 // Explicit label after break/continue. | 4985 // Explicit label after break/continue. |
| 4993 const String& target_name = *CurrentLiteral(); | 4986 const String& target_name = *CurrentLiteral(); |
| 4994 ConsumeToken(); | 4987 ConsumeToken(); |
| 4995 // Handle pathological cases first. | 4988 // Handle pathological cases first. |
| 4996 if (label_name != NULL && target_name.Equals(*label_name)) { | 4989 if (label_name != NULL && target_name.Equals(*label_name)) { |
| 4997 if (jump_kind == Token::kCONTINUE) { | 4990 if (jump_kind == Token::kCONTINUE) { |
| 4998 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 4991 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", |
| 4999 target_name.ToCString()); | 4992 target_name.ToCString()); |
| 5000 } | 4993 } |
| 5001 // L: break L; is a no-op. | 4994 // L: break L; is a no-op. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5037 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); | 5030 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); |
| 5038 } | 5031 } |
| 5039 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 5032 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 5040 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 5033 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
| 5041 Token::Str(jump_kind)); | 5034 Token::Str(jump_kind)); |
| 5042 } | 5035 } |
| 5043 return new JumpNode(jump_pos, jump_kind, target); | 5036 return new JumpNode(jump_pos, jump_kind, target); |
| 5044 } | 5037 } |
| 5045 | 5038 |
| 5046 | 5039 |
| 5040 bool Parser::IsDefinedInLexicalScope(const String& ident) { |
| 5041 if (ResolveIdentInLocalScope(token_index_, ident, NULL)) { |
| 5042 return true; |
| 5043 } |
| 5044 Object& obj = Object::Handle(); |
| 5045 obj = library_.LookupObject(ident); |
| 5046 return !obj.IsNull(); |
| 5047 } |
| 5048 |
| 5049 |
| 5047 AstNode* Parser::ParseStatement() { | 5050 AstNode* Parser::ParseStatement() { |
| 5048 TRACE_PARSER("ParseStatement"); | 5051 TRACE_PARSER("ParseStatement"); |
| 5049 AstNode* statement = NULL; | 5052 AstNode* statement = NULL; |
| 5050 intptr_t label_pos = 0; | 5053 intptr_t label_pos = 0; |
| 5051 String* label_name = NULL; | 5054 String* label_name = NULL; |
| 5052 if (CurrentToken() == Token::kIDENT) { | 5055 if (IsIdentifier()) { |
| 5053 if (LookaheadToken(1) == Token::kCOLON) { | 5056 if (LookaheadToken(1) == Token::kCOLON) { |
| 5054 // Statement starts with a label. | 5057 // Statement starts with a label. |
| 5055 label_name = CurrentLiteral(); | 5058 label_name = CurrentLiteral(); |
| 5056 label_pos = token_index_; | 5059 label_pos = token_index_; |
| 5057 ASSERT(label_pos > 0); | 5060 ASSERT(label_pos > 0); |
| 5058 ConsumeToken(); // Consume identifier. | 5061 ConsumeToken(); // Consume identifier. |
| 5059 ConsumeToken(); // Consume colon. | 5062 ConsumeToken(); // Consume colon. |
| 5060 } | 5063 } |
| 5061 } | 5064 } |
| 5062 const intptr_t statement_pos = token_index_; | 5065 const intptr_t statement_pos = token_index_; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 5081 } | 5084 } |
| 5082 AstNode* expr = ParseExpr(kAllowConst); | 5085 AstNode* expr = ParseExpr(kAllowConst); |
| 5083 statement = new ReturnNode(statement_pos, expr); | 5086 statement = new ReturnNode(statement_pos, expr); |
| 5084 } else { | 5087 } else { |
| 5085 statement = new ReturnNode(statement_pos); | 5088 statement = new ReturnNode(statement_pos); |
| 5086 } | 5089 } |
| 5087 AddNodeForFinallyInlining(statement); | 5090 AddNodeForFinallyInlining(statement); |
| 5088 ExpectSemicolon(); | 5091 ExpectSemicolon(); |
| 5089 } else if (CurrentToken() == Token::kIF) { | 5092 } else if (CurrentToken() == Token::kIF) { |
| 5090 statement = ParseIfStatement(label_name); | 5093 statement = ParseIfStatement(label_name); |
| 5091 } else if (CurrentToken() == Token::kASSERT) { | 5094 } else if ((CurrentToken() == Token::kASSERT) && |
| 5095 !IsDefinedInLexicalScope(*CurrentLiteral())) { |
| 5092 statement = ParseAssertStatement(); | 5096 statement = ParseAssertStatement(); |
| 5093 ExpectSemicolon(); | 5097 ExpectSemicolon(); |
| 5094 } else if (IsVariableDeclaration()) { | 5098 } else if (IsVariableDeclaration()) { |
| 5095 statement = ParseVariableDeclarationList(); | 5099 statement = ParseVariableDeclarationList(); |
| 5096 ExpectSemicolon(); | 5100 ExpectSemicolon(); |
| 5097 } else if (IsFunctionDeclaration()) { | 5101 } else if (IsFunctionDeclaration()) { |
| 5098 statement = ParseFunctionStatement(false); | 5102 statement = ParseFunctionStatement(false); |
| 5099 } else if (CurrentToken() == Token::kLBRACE) { | 5103 } else if (CurrentToken() == Token::kLBRACE) { |
| 5100 SourceLabel* label = NULL; | 5104 SourceLabel* label = NULL; |
| 5101 OpenBlock(); | 5105 OpenBlock(); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5307 } | 5311 } |
| 5308 | 5312 |
| 5309 | 5313 |
| 5310 void Parser::UnexpectedToken() { | 5314 void Parser::UnexpectedToken() { |
| 5311 ErrorMsg("unexpected token '%s'", | 5315 ErrorMsg("unexpected token '%s'", |
| 5312 CurrentToken() == Token::kIDENT ? | 5316 CurrentToken() == Token::kIDENT ? |
| 5313 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 5317 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); |
| 5314 } | 5318 } |
| 5315 | 5319 |
| 5316 | 5320 |
| 5317 String* Parser::ExpectIdentifier(const char* msg) { | 5321 String* Parser::ExpectTypeIdentifier(const char* msg) { |
| 5318 if (CurrentToken() != Token::kIDENT) { | 5322 if (CurrentToken() != Token::kIDENT) { |
| 5319 ErrorMsg(msg); | 5323 ErrorMsg(msg); |
| 5320 } | 5324 } |
| 5321 String* ident = CurrentLiteral(); | 5325 String* ident = CurrentLiteral(); |
| 5322 ConsumeToken(); | 5326 ConsumeToken(); |
| 5323 return ident; | 5327 return ident; |
| 5324 } | 5328 } |
| 5325 | 5329 |
| 5330 // Check whether current token is an identifier or a built-in identifier. |
| 5331 String* Parser::ExpectIdentifier(const char* msg) { |
| 5332 if (!IsIdentifier()) { |
| 5333 ErrorMsg(msg); |
| 5334 } |
| 5335 String* ident = CurrentLiteral(); |
| 5336 ConsumeToken(); |
| 5337 return ident; |
| 5338 } |
| 5339 |
| 5326 | 5340 |
| 5327 bool Parser::IsLiteral(const char* literal) { | 5341 bool Parser::IsLiteral(const char* literal) { |
| 5328 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); | 5342 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); |
| 5329 intptr_t len = strlen(literal); | 5343 intptr_t len = strlen(literal); |
| 5330 return (CurrentToken() == Token::kIDENT) | 5344 return IsIdentifier() && CurrentLiteral()->Equals(characters, len); |
| 5331 && CurrentLiteral()->Equals(characters, len); | |
| 5332 } | 5345 } |
| 5333 | 5346 |
| 5334 | 5347 |
| 5335 bool Parser::IsIncrementOperator(Token::Kind token) { | 5348 bool Parser::IsIncrementOperator(Token::Kind token) { |
| 5336 return token == Token::kINCR || token == Token::kDECR; | 5349 return token == Token::kINCR || token == Token::kDECR; |
| 5337 } | 5350 } |
| 5338 | 5351 |
| 5339 | 5352 |
| 5340 bool Parser::IsPrefixOperator(Token::Kind token) { | 5353 bool Parser::IsPrefixOperator(Token::Kind token) { |
| 5341 return token == Token::kADD || token == Token::kSUB | 5354 return token == Token::kADD || token == Token::kSUB |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5697 } else { | 5710 } else { |
| 5698 arguments = implicit_arguments; | 5711 arguments = implicit_arguments; |
| 5699 } | 5712 } |
| 5700 GrowableArray<const String*> names; | 5713 GrowableArray<const String*> names; |
| 5701 bool named_argument_seen = false; | 5714 bool named_argument_seen = false; |
| 5702 if (LookaheadToken(1) != Token::kRPAREN) { | 5715 if (LookaheadToken(1) != Token::kRPAREN) { |
| 5703 do { | 5716 do { |
| 5704 ASSERT((CurrentToken() == Token::kLPAREN) || | 5717 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 5705 (CurrentToken() == Token::kCOMMA)); | 5718 (CurrentToken() == Token::kCOMMA)); |
| 5706 ConsumeToken(); | 5719 ConsumeToken(); |
| 5707 if ((CurrentToken() == Token::kIDENT) && | 5720 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 5708 (LookaheadToken(1) == Token::kCOLON)) { | |
| 5709 named_argument_seen = true; | 5721 named_argument_seen = true; |
| 5710 // The canonicalization of the argument descriptor array built in the | 5722 // The canonicalization of the argument descriptor array built in the |
| 5711 // code generator requires that the names are symbols, i.e. | 5723 // code generator requires that the names are symbols, i.e. |
| 5712 // canonicalized strings. | 5724 // canonicalized strings. |
| 5713 ASSERT(CurrentLiteral()->IsSymbol()); | 5725 ASSERT(CurrentLiteral()->IsSymbol()); |
| 5714 for (int i = 0; i < names.length(); i++) { | 5726 for (int i = 0; i < names.length(); i++) { |
| 5715 if (CurrentLiteral()->Equals(*names[i])) { | 5727 if (CurrentLiteral()->Equals(*names[i])) { |
| 5716 ErrorMsg("duplicate named argument"); | 5728 ErrorMsg("duplicate named argument"); |
| 5717 } | 5729 } |
| 5718 } | 5730 } |
| (...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7082 return constructor_name; | 7094 return constructor_name; |
| 7083 } | 7095 } |
| 7084 | 7096 |
| 7085 | 7097 |
| 7086 AstNode* Parser::ParseNewOperator() { | 7098 AstNode* Parser::ParseNewOperator() { |
| 7087 TRACE_PARSER("ParseNewOperator"); | 7099 TRACE_PARSER("ParseNewOperator"); |
| 7088 const intptr_t new_pos = token_index_; | 7100 const intptr_t new_pos = token_index_; |
| 7089 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7101 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7090 bool is_const = (CurrentToken() == Token::kCONST); | 7102 bool is_const = (CurrentToken() == Token::kCONST); |
| 7091 ConsumeToken(); | 7103 ConsumeToken(); |
| 7092 if (CurrentToken() != Token::kIDENT) { | 7104 if (!IsIdentifier()) { |
| 7093 ErrorMsg("type name expected"); | 7105 ErrorMsg("type name expected"); |
| 7094 } | 7106 } |
| 7095 | 7107 |
| 7096 // The grammar allows for an optional ('.' identifier)?, which is a named | 7108 // The grammar allows for an optional ('.' identifier)?, which is a named |
| 7097 // constructor. For that reason, we cannot unconditionally call | 7109 // constructor. For that reason, we cannot unconditionally call |
| 7098 // ParseType(kMustResolve) after we see an identifier, because the named | 7110 // ParseType(kMustResolve) after we see an identifier, because the named |
| 7099 // constructor would be misinterpreted as a qualified type name. | 7111 // constructor would be misinterpreted as a qualified type name. |
| 7100 // TODO(regis): Revisit once we correctly support qualified identifiers. | 7112 // TODO(regis): Revisit once we correctly support qualified identifiers. |
| 7101 // For now, we inline a customized version of ParseType(kMustResolve). | 7113 // For now, we inline a customized version of ParseType(kMustResolve). |
| 7102 const intptr_t type_pos = token_index_; | 7114 const intptr_t type_pos = token_index_; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7343 | 7355 |
| 7344 AstNode* Parser::ParsePrimary() { | 7356 AstNode* Parser::ParsePrimary() { |
| 7345 TRACE_PARSER("ParsePrimary"); | 7357 TRACE_PARSER("ParsePrimary"); |
| 7346 AstNode* primary = NULL; | 7358 AstNode* primary = NULL; |
| 7347 if (IsFunctionLiteral()) { | 7359 if (IsFunctionLiteral()) { |
| 7348 // The name of a literal function is visible from inside the function, but | 7360 // The name of a literal function is visible from inside the function, but |
| 7349 // must not collide with names in the scope declaring the literal. | 7361 // must not collide with names in the scope declaring the literal. |
| 7350 OpenBlock(); | 7362 OpenBlock(); |
| 7351 primary = ParseFunctionStatement(true); | 7363 primary = ParseFunctionStatement(true); |
| 7352 CloseBlock(); | 7364 CloseBlock(); |
| 7353 } else if (CurrentToken() == Token::kIDENT) { | 7365 } else if (IsIdentifier()) { |
| 7354 QualIdent qual_ident; | 7366 QualIdent qual_ident; |
| 7355 ParseQualIdent(&qual_ident); | 7367 ParseQualIdent(&qual_ident); |
| 7356 if (qual_ident.is_local_scope_ident) { | 7368 if (qual_ident.is_local_scope_ident) { |
| 7357 ResolveIdentInLocalScope(qual_ident.ident_pos, | 7369 ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 7358 *qual_ident.ident, | 7370 *qual_ident.ident, |
| 7359 &primary); | 7371 &primary); |
| 7360 } else { | 7372 } else { |
| 7361 if (qual_ident.qualifier == NULL) { | 7373 if (qual_ident.qualifier == NULL) { |
| 7362 // This is an unqualified identifier so resolve the identifier | 7374 // This is an unqualified identifier so resolve the identifier |
| 7363 // locally in the main app library and all libraries imported by it. | 7375 // locally in the main app library and all libraries imported by it. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7479 Instance& value = Instance::ZoneHandle(Compiler::ExecuteOnce(seq)); | 7491 Instance& value = Instance::ZoneHandle(Compiler::ExecuteOnce(seq)); |
| 7480 if (value.IsNull()) { | 7492 if (value.IsNull()) { |
| 7481 value ^= value.Canonicalize(); | 7493 value ^= value.Canonicalize(); |
| 7482 } | 7494 } |
| 7483 return value; | 7495 return value; |
| 7484 } | 7496 } |
| 7485 } | 7497 } |
| 7486 | 7498 |
| 7487 | 7499 |
| 7488 void Parser::SkipFunctionLiteral() { | 7500 void Parser::SkipFunctionLiteral() { |
| 7489 if (CurrentToken() == Token::kIDENT) { | 7501 if (IsIdentifier()) { |
| 7490 if (LookaheadToken(1) != Token::kLPAREN) { | 7502 if (LookaheadToken(1) != Token::kLPAREN) { |
| 7491 SkipType(true); | 7503 SkipType(true); |
| 7492 } | 7504 } |
| 7493 ExpectIdentifier("function name expected"); | 7505 ExpectIdentifier("function name expected"); |
| 7494 } | 7506 } |
| 7495 if (CurrentToken() == Token::kLPAREN) { | 7507 if (CurrentToken() == Token::kLPAREN) { |
| 7496 const bool allow_explicit_default_values = true; | 7508 const bool allow_explicit_default_values = true; |
| 7497 ParamList ignore_params; | 7509 ParamList ignore_params; |
| 7498 ParseFormalParameterList(allow_explicit_default_values, &ignore_params); | 7510 ParseFormalParameterList(allow_explicit_default_values, &ignore_params); |
| 7499 } | 7511 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7557 (CurrentToken() == Token::kINDEX)) { | 7569 (CurrentToken() == Token::kINDEX)) { |
| 7558 SkipListLiteral(); | 7570 SkipListLiteral(); |
| 7559 } else if (CurrentToken() == Token::kLBRACE) { | 7571 } else if (CurrentToken() == Token::kLBRACE) { |
| 7560 SkipMapLiteral(); | 7572 SkipMapLiteral(); |
| 7561 } | 7573 } |
| 7562 } | 7574 } |
| 7563 | 7575 |
| 7564 | 7576 |
| 7565 void Parser::SkipNewOperator() { | 7577 void Parser::SkipNewOperator() { |
| 7566 ConsumeToken(); // Skip new or const keyword. | 7578 ConsumeToken(); // Skip new or const keyword. |
| 7567 if (CurrentToken() == Token::kIDENT) { | 7579 if (IsIdentifier()) { |
| 7568 SkipType(false); | 7580 SkipType(false); |
| 7569 if (CurrentToken() == Token::kLPAREN) { | 7581 if (CurrentToken() == Token::kLPAREN) { |
| 7570 SkipActualParameters(); | 7582 SkipActualParameters(); |
| 7571 return; | 7583 return; |
| 7572 } | 7584 } |
| 7573 } | 7585 } |
| 7574 } | 7586 } |
| 7575 | 7587 |
| 7576 | 7588 |
| 7577 void Parser::SkipStringLiteral() { | 7589 void Parser::SkipStringLiteral() { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7637 SkipNewOperator(); | 7649 SkipNewOperator(); |
| 7638 } | 7650 } |
| 7639 break; | 7651 break; |
| 7640 case Token::kLT: | 7652 case Token::kLT: |
| 7641 case Token::kLBRACE: | 7653 case Token::kLBRACE: |
| 7642 case Token::kLBRACK: | 7654 case Token::kLBRACK: |
| 7643 case Token::kINDEX: | 7655 case Token::kINDEX: |
| 7644 SkipCompoundLiteral(); | 7656 SkipCompoundLiteral(); |
| 7645 break; | 7657 break; |
| 7646 default: | 7658 default: |
| 7647 UnexpectedToken(); | 7659 if (IsIdentifier()) { |
| 7648 UNREACHABLE(); | 7660 ConsumeToken(); // Handle pseudo-keyword identifiers. |
| 7661 } else { |
| 7662 UnexpectedToken(); |
| 7663 UNREACHABLE(); |
| 7664 } |
| 7649 break; | 7665 break; |
| 7650 } | 7666 } |
| 7651 } | 7667 } |
| 7652 | 7668 |
| 7653 | 7669 |
| 7654 void Parser::SkipPostfixExpr() { | 7670 void Parser::SkipPostfixExpr() { |
| 7655 SkipPrimary(); | 7671 SkipPrimary(); |
| 7656 while (true) { | 7672 while (true) { |
| 7657 if (CurrentToken() == Token::kPERIOD) { | 7673 if (CurrentToken() == Token::kPERIOD) { |
| 7658 ConsumeToken(); | 7674 ConsumeToken(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7714 } | 7730 } |
| 7715 | 7731 |
| 7716 | 7732 |
| 7717 void Parser::SkipNestedExpr() { | 7733 void Parser::SkipNestedExpr() { |
| 7718 const bool saved_mode = SetAllowFunctionLiterals(true); | 7734 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7719 SkipExpr(); | 7735 SkipExpr(); |
| 7720 SetAllowFunctionLiterals(saved_mode); | 7736 SetAllowFunctionLiterals(saved_mode); |
| 7721 } | 7737 } |
| 7722 | 7738 |
| 7723 } // namespace dart | 7739 } // namespace dart |
| OLD | NEW |