Chromium Code Reviews| 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)) { | |
| 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)) { | |
| 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)) { | |
| 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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3281 ConsumeToken(); | 3276 ConsumeToken(); |
| 3282 ExpectToken(Token::kLPAREN); | 3277 ExpectToken(Token::kLPAREN); |
| 3283 if (CurrentToken() != Token::kSTRING) { | 3278 if (CurrentToken() != Token::kSTRING) { |
| 3284 ErrorMsg("library url expected"); | 3279 ErrorMsg("library url expected"); |
| 3285 } | 3280 } |
| 3286 const String& url = *CurrentLiteral(); | 3281 const String& url = *CurrentLiteral(); |
| 3287 ConsumeToken(); | 3282 ConsumeToken(); |
| 3288 String& prefix = String::Handle(); | 3283 String& prefix = String::Handle(); |
| 3289 if (CurrentToken() == Token::kCOMMA) { | 3284 if (CurrentToken() == Token::kCOMMA) { |
| 3290 ConsumeToken(); | 3285 ConsumeToken(); |
| 3291 const String& kPrefix = String::Handle(String::NewSymbol("prefix")); | 3286 if (!IsLiteral("prefix")) { |
| 3292 if ((CurrentToken() != Token::kIDENT) || | |
| 3293 !kPrefix.Equals(*CurrentLiteral())) { | |
| 3294 ErrorMsg("prefix: expected"); | 3287 ErrorMsg("prefix: expected"); |
| 3295 } | 3288 } |
| 3296 ConsumeToken(); | 3289 ConsumeToken(); |
| 3297 ExpectToken(Token::kCOLON); | 3290 ExpectToken(Token::kCOLON); |
| 3298 if (CurrentToken() != Token::kSTRING) { | 3291 if (CurrentToken() != Token::kSTRING) { |
| 3299 ErrorMsg("prefix expected"); | 3292 ErrorMsg("prefix expected"); |
| 3300 } | 3293 } |
| 3301 prefix = CurrentLiteral()->raw(); | 3294 prefix = CurrentLiteral()->raw(); |
| 3302 // TODO(asiva): Need to also check that prefix is not a reserved keyword. | 3295 // TODO(asiva): Need to also check that prefix is not a reserved keyword. |
| 3303 if (!Scanner::IsIdent(prefix)) { | 3296 if (!Scanner::IsIdent(prefix)) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3382 toplevel_class.set_library(library_); | 3375 toplevel_class.set_library(library_); |
| 3383 | 3376 |
| 3384 if (is_library_source()) { | 3377 if (is_library_source()) { |
| 3385 ParseLibraryDefinition(); | 3378 ParseLibraryDefinition(); |
| 3386 } | 3379 } |
| 3387 | 3380 |
| 3388 while (true) { | 3381 while (true) { |
| 3389 set_current_class(Class::Handle()); // No current class. | 3382 set_current_class(Class::Handle()); // No current class. |
| 3390 if (CurrentToken() == Token::kCLASS) { | 3383 if (CurrentToken() == Token::kCLASS) { |
| 3391 ParseClassDefinition(&classes); | 3384 ParseClassDefinition(&classes); |
| 3392 } else if (CurrentToken() == Token::kTYPEDEF) { | 3385 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 3386 (LookaheadToken(1) != Token::kLPAREN)) { | |
| 3393 ParseFunctionTypeAlias(&classes); | 3387 ParseFunctionTypeAlias(&classes); |
| 3394 } else if (CurrentToken() == Token::kINTERFACE) { | 3388 } else if (CurrentToken() == Token::kINTERFACE) { |
| 3395 ParseInterfaceDefinition(&classes); | 3389 ParseInterfaceDefinition(&classes); |
| 3396 } else if (IsVariableDeclaration()) { | 3390 } else if (IsVariableDeclaration()) { |
| 3397 set_current_class(toplevel_class); | 3391 set_current_class(toplevel_class); |
| 3398 ParseTopLevelVariable(&top_level); | 3392 ParseTopLevelVariable(&top_level); |
| 3399 } else if (IsTopLevelFunction()) { | 3393 } else if (IsTopLevelFunction()) { |
| 3400 set_current_class(toplevel_class); | 3394 set_current_class(toplevel_class); |
| 3401 ParseTopLevelFunction(&top_level); | 3395 ParseTopLevelFunction(&top_level); |
| 3402 } else if (IsTopLevelAccessor()) { | 3396 } else if (IsTopLevelAccessor()) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3619 AstNode* object, | 3613 AstNode* object, |
| 3620 const String& name) { | 3614 const String& name) { |
| 3621 return new InstanceGetterNode(token_index_, object, name); | 3615 return new InstanceGetterNode(token_index_, object, name); |
| 3622 } | 3616 } |
| 3623 | 3617 |
| 3624 | 3618 |
| 3625 // Returns ast nodes of the variable initialization. | 3619 // Returns ast nodes of the variable initialization. |
| 3626 AstNode* Parser::ParseVariableDeclaration( | 3620 AstNode* Parser::ParseVariableDeclaration( |
| 3627 const AbstractType& type, bool is_final) { | 3621 const AbstractType& type, bool is_final) { |
| 3628 TRACE_PARSER("ParseVariableDeclaration"); | 3622 TRACE_PARSER("ParseVariableDeclaration"); |
| 3629 ASSERT(CurrentToken() == Token::kIDENT); | 3623 ASSERT(IsIdentifier()); |
| 3630 const intptr_t ident_pos = token_index_; | 3624 const intptr_t ident_pos = token_index_; |
| 3631 LocalVariable* variable = | 3625 LocalVariable* variable = |
| 3632 new LocalVariable(ident_pos, *CurrentLiteral(), type); | 3626 new LocalVariable(ident_pos, *CurrentLiteral(), type); |
| 3633 ASSERT(current_block_ != NULL); | 3627 ASSERT(current_block_ != NULL); |
| 3634 ASSERT(current_block_->scope != NULL); | 3628 ASSERT(current_block_->scope != NULL); |
| 3635 ConsumeToken(); // Variable identifier. | 3629 ConsumeToken(); // Variable identifier. |
| 3636 AstNode* initialization = NULL; | 3630 AstNode* initialization = NULL; |
| 3637 if (CurrentToken() == Token::kASSIGN) { | 3631 if (CurrentToken() == Token::kASSIGN) { |
| 3638 // Variable initialization. | 3632 // Variable initialization. |
| 3639 const intptr_t assign_pos = token_index_; | 3633 const intptr_t assign_pos = token_index_; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3672 return Type::DynamicType(); | 3666 return Type::DynamicType(); |
| 3673 } | 3667 } |
| 3674 if (CurrentToken() == Token::kFINAL) { | 3668 if (CurrentToken() == Token::kFINAL) { |
| 3675 ConsumeToken(); | 3669 ConsumeToken(); |
| 3676 type_specification = kIsOptional; | 3670 type_specification = kIsOptional; |
| 3677 } | 3671 } |
| 3678 if (CurrentToken() != Token::kIDENT) { | 3672 if (CurrentToken() != Token::kIDENT) { |
| 3679 if (type_specification == kIsOptional) { | 3673 if (type_specification == kIsOptional) { |
| 3680 return Type::DynamicType(); | 3674 return Type::DynamicType(); |
| 3681 } else { | 3675 } else { |
| 3682 ErrorMsg("identifier expected"); | 3676 ErrorMsg("type name expected"); |
| 3683 } | 3677 } |
| 3684 } | 3678 } |
| 3685 if (type_specification == kIsOptional) { | 3679 if (type_specification == kIsOptional) { |
| 3686 Token::Kind follower = LookaheadToken(1); | 3680 Token::Kind follower = LookaheadToken(1); |
| 3687 // We have an identifier followed by a 'follower' token. | 3681 // We have an identifier followed by a 'follower' token. |
| 3688 // We either parse a type or return now. | 3682 // We either parse a type or return now. |
| 3689 if ((follower != Token::kLT) && // Parameterized type. | 3683 if ((follower != Token::kLT) && // Parameterized type. |
| 3690 (follower != Token::kPERIOD) && // Qualified class name of type. | 3684 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 3691 (follower != Token::kIDENT) && // Variable name following a type. | 3685 !Token::IsIdentifier(follower) && // Variable name following a type. |
| 3692 (follower != Token::kTHIS)) { // Field parameter following a type. | 3686 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 3693 return Type::DynamicType(); | 3687 return Type::DynamicType(); |
| 3694 } | 3688 } |
| 3695 } | 3689 } |
| 3696 return ParseType(type_resolution); | 3690 return ParseType(type_resolution); |
| 3697 } | 3691 } |
| 3698 | 3692 |
| 3699 | 3693 |
| 3700 // Returns ast nodes of the variable initialization. Variables without an | 3694 // Returns ast nodes of the variable initialization. Variables without an |
| 3701 // explicit initializer are initialized to null. If several variables are | 3695 // explicit initializer are initialized to null. If several variables are |
| 3702 // declared, the individual initializers are collected in a sequence node. | 3696 // declared, the individual initializers are collected in a sequence node. |
| 3703 AstNode* Parser::ParseVariableDeclarationList() { | 3697 AstNode* Parser::ParseVariableDeclarationList() { |
| 3704 TRACE_PARSER("ParseVariableDeclarationList"); | 3698 TRACE_PARSER("ParseVariableDeclarationList"); |
| 3705 bool is_final = (CurrentToken() == Token::kFINAL); | 3699 bool is_final = (CurrentToken() == Token::kFINAL); |
| 3706 const AbstractType& type = AbstractType::ZoneHandle( | 3700 const AbstractType& type = AbstractType::ZoneHandle( |
| 3707 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 3701 ParseFinalVarOrType(kIsMandatory, kMustResolve)); |
| 3708 if (CurrentToken() != Token::kIDENT) { | 3702 if (!IsIdentifier()) { |
| 3709 ErrorMsg("identifier expected"); | 3703 ErrorMsg("identifier expected"); |
| 3710 } | 3704 } |
| 3711 | 3705 |
| 3712 AstNode* initializers = ParseVariableDeclaration(type, is_final); | 3706 AstNode* initializers = ParseVariableDeclaration(type, is_final); |
| 3713 ASSERT(initializers != NULL); | 3707 ASSERT(initializers != NULL); |
| 3714 while (CurrentToken() == Token::kCOMMA) { | 3708 while (CurrentToken() == Token::kCOMMA) { |
| 3715 ConsumeToken(); | 3709 ConsumeToken(); |
| 3716 if (CurrentToken() != Token::kIDENT) { | 3710 if (!IsIdentifier()) { |
| 3717 ErrorMsg("identifier expected after comma"); | 3711 ErrorMsg("identifier expected after comma"); |
| 3718 } | 3712 } |
| 3719 // We have a second initializer. Allocate a sequence node now. | 3713 // We have a second initializer. Allocate a sequence node now. |
| 3720 // The sequence does not own the current scope. Set its own scope to NULL. | 3714 // The sequence does not own the current scope. Set its own scope to NULL. |
| 3721 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_index(), | 3715 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_index(), |
| 3722 initializers, | 3716 initializers, |
| 3723 NULL); | 3717 NULL); |
| 3724 sequence->Add(ParseVariableDeclaration(type, is_final)); | 3718 sequence->Add(ParseVariableDeclaration(type, is_final)); |
| 3725 initializers = sequence; | 3719 initializers = sequence; |
| 3726 } | 3720 } |
| 3727 return initializers; | 3721 return initializers; |
| 3728 } | 3722 } |
| 3729 | 3723 |
| 3730 | 3724 |
| 3731 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 3725 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 3732 TRACE_PARSER("ParseFunctionStatement"); | 3726 TRACE_PARSER("ParseFunctionStatement"); |
| 3733 AbstractType& result_type = AbstractType::Handle(); | 3727 AbstractType& result_type = AbstractType::Handle(); |
| 3734 const String* variable_name = NULL; | 3728 const String* variable_name = NULL; |
| 3735 const String* function_name = NULL; | 3729 const String* function_name = NULL; |
| 3736 | 3730 |
| 3737 result_type = Type::DynamicType(); | 3731 result_type = Type::DynamicType(); |
| 3738 if (CurrentToken() == Token::kVOID) { | 3732 if (CurrentToken() == Token::kVOID) { |
| 3739 ConsumeToken(); | 3733 ConsumeToken(); |
| 3740 result_type = Type::VoidType(); | 3734 result_type = Type::VoidType(); |
| 3741 } else if ((CurrentToken() == Token::kIDENT) && | 3735 } else if ((CurrentToken() == Token::kIDENT) && |
| 3742 (LookaheadToken(1) != Token::kLPAREN)) { | 3736 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3743 result_type = ParseType(kMustResolve); | 3737 result_type = ParseType(kMustResolve); |
| 3744 } | 3738 } |
| 3745 const intptr_t ident_pos = token_index_; | 3739 const intptr_t ident_pos = token_index_; |
| 3746 if (CurrentToken() == Token::kIDENT) { | 3740 if (IsIdentifier()) { |
| 3747 variable_name = CurrentLiteral(); | 3741 variable_name = CurrentLiteral(); |
| 3748 function_name = variable_name; | 3742 function_name = variable_name; |
| 3749 ConsumeToken(); | 3743 ConsumeToken(); |
| 3750 } else { | 3744 } else { |
| 3751 if (!is_literal) { | 3745 if (!is_literal) { |
| 3752 ErrorMsg("function name expected"); | 3746 ErrorMsg("function name expected"); |
| 3753 } | 3747 } |
| 3754 const String& anonymous_function_name = | 3748 const String& anonymous_function_name = |
| 3755 String::ZoneHandle(String::NewSymbol("function")); | 3749 String::ZoneHandle(String::NewSymbol("function")); |
| 3756 function_name = &anonymous_function_name; | 3750 function_name = &anonymous_function_name; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3929 ConsumeToken(); | 3923 ConsumeToken(); |
| 3930 } while (nesting_level > 0); | 3924 } while (nesting_level > 0); |
| 3931 if (nesting_level < 0) { | 3925 if (nesting_level < 0) { |
| 3932 return false; | 3926 return false; |
| 3933 } | 3927 } |
| 3934 } | 3928 } |
| 3935 return true; | 3929 return true; |
| 3936 } | 3930 } |
| 3937 | 3931 |
| 3938 | 3932 |
| 3933 // Returns true if the current token is kIDENT or a pseudo-keyword. | |
| 3934 bool Parser::IsIdentifier() { | |
| 3935 return Token::IsIdentifier(CurrentToken()); | |
| 3936 } | |
| 3937 | |
| 3938 | |
| 3939 // Returns true if the next tokens can be parsed as a type with optional | 3939 // Returns true if the next tokens can be parsed as a type with optional |
| 3940 // type parameters. Current token position is not restored. | 3940 // type parameters. Current token position is not restored. |
| 3941 bool Parser::IsOptionalType() { | 3941 bool Parser::IsOptionalType() { |
| 3942 if (CurrentToken() == Token::kIDENT) { | 3942 if (CurrentToken() == Token::kIDENT) { |
| 3943 QualIdent type_name; | 3943 QualIdent type_name; |
| 3944 ParseQualIdent(&type_name); | 3944 ParseQualIdent(&type_name); |
| 3945 // Check if the type_name has been defined as a variable in a local scope, | 3945 // Check if the type_name has been defined as a variable in a local scope, |
| 3946 // hiding the type. | 3946 // hiding the type. |
| 3947 if (type_name.is_local_scope_ident) { | 3947 if (type_name.is_local_scope_ident) { |
| 3948 return false; | 3948 return false; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 3972 // Look ahead to detect whether the next tokens should be parsed as | 3972 // Look ahead to detect whether the next tokens should be parsed as |
| 3973 // a variable declaration. Returns true if we detect the token pattern: | 3973 // a variable declaration. Returns true if we detect the token pattern: |
| 3974 // ('var' | 'final' | type ident (';' | '=' | ',')) | 3974 // ('var' | 'final' | type ident (';' | '=' | ',')) |
| 3975 // Token position remains unchanged. | 3975 // Token position remains unchanged. |
| 3976 bool Parser::IsVariableDeclaration() { | 3976 bool Parser::IsVariableDeclaration() { |
| 3977 if ((CurrentToken() == Token::kVAR) || | 3977 if ((CurrentToken() == Token::kVAR) || |
| 3978 (CurrentToken() == Token::kFINAL)) { | 3978 (CurrentToken() == Token::kFINAL)) { |
| 3979 return true; | 3979 return true; |
| 3980 } | 3980 } |
| 3981 if (CurrentToken() != Token::kIDENT) { | 3981 if (CurrentToken() != Token::kIDENT) { |
| 3982 // Not a legal type identifier. | |
| 3982 return false; | 3983 return false; |
| 3983 } | 3984 } |
| 3984 const intptr_t saved_pos = token_index_; | 3985 const intptr_t saved_pos = token_index_; |
| 3985 bool is_var_decl = false; | 3986 bool is_var_decl = false; |
| 3986 if (IsOptionalType()) { | 3987 if (IsOptionalType()) { |
| 3987 if (CurrentToken() == Token::kIDENT) { | 3988 if (IsIdentifier()) { |
| 3988 ConsumeToken(); | 3989 ConsumeToken(); |
| 3989 if ((CurrentToken() == Token::kSEMICOLON) || | 3990 if ((CurrentToken() == Token::kSEMICOLON) || |
| 3990 (CurrentToken() == Token::kCOMMA) || | 3991 (CurrentToken() == Token::kCOMMA) || |
| 3991 (CurrentToken() == Token::kASSIGN)) { | 3992 (CurrentToken() == Token::kASSIGN)) { |
| 3992 is_var_decl = true; | 3993 is_var_decl = true; |
| 3993 } | 3994 } |
| 3994 } | 3995 } |
| 3995 } | 3996 } |
| 3996 SetPosition(saved_pos); | 3997 SetPosition(saved_pos); |
| 3997 return is_var_decl; | 3998 return is_var_decl; |
| 3998 } | 3999 } |
| 3999 | 4000 |
| 4000 | 4001 |
| 4001 bool Parser::IsFunctionDeclaration() { | 4002 bool Parser::IsFunctionDeclaration() { |
| 4002 // A function declaration is like a function literal but it must have | 4003 // A function declaration is like a function literal but it must have |
| 4003 // a name. | 4004 // a name. |
| 4004 return (CurrentToken() != Token::kLPAREN) && IsFunctionLiteral(); | 4005 return (CurrentToken() != Token::kLPAREN) && IsFunctionLiteral(); |
| 4005 } | 4006 } |
| 4006 | 4007 |
| 4007 | 4008 |
| 4008 bool Parser::IsTopLevelFunction() { | 4009 bool Parser::IsTopLevelFunction() { |
| 4009 // Top-level function declarations can omit the return type. Check for | 4010 // Top-level function declarations can omit the return type. Check for |
| 4010 // that case separately. | 4011 // that case separately. |
| 4011 return ((CurrentToken() == Token::kIDENT) && | 4012 return (IsIdentifier() && |
| 4012 (LookaheadToken(1) == Token::kLPAREN)) || | 4013 (LookaheadToken(1) == Token::kLPAREN)) || IsFunctionDeclaration(); |
| 4013 IsFunctionDeclaration(); | |
| 4014 } | 4014 } |
| 4015 | 4015 |
| 4016 | 4016 |
| 4017 bool Parser::IsTopLevelAccessor() { | 4017 bool Parser::IsTopLevelAccessor() { |
| 4018 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4018 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4019 return true; | 4019 return true; |
| 4020 } | 4020 } |
| 4021 const intptr_t saved_pos = token_index_; | 4021 const intptr_t saved_pos = token_index_; |
| 4022 if (IsReturnType()) { | 4022 if (IsReturnType()) { |
| 4023 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4023 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4024 if (LookaheadToken(1) == Token::kIDENT) { // Accessor name. | 4024 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 4025 SetPosition(saved_pos); | 4025 SetPosition(saved_pos); |
| 4026 return true; | 4026 return true; |
| 4027 } | 4027 } |
| 4028 } | 4028 } |
| 4029 } | 4029 } |
| 4030 SetPosition(saved_pos); | 4030 SetPosition(saved_pos); |
| 4031 return false; | 4031 return false; |
| 4032 } | 4032 } |
| 4033 | 4033 |
| 4034 | 4034 |
| 4035 bool Parser::IsFunctionLiteral() { | 4035 bool Parser::IsFunctionLiteral() { |
| 4036 if (!allow_function_literals_) { | 4036 if (!allow_function_literals_) { |
| 4037 return false; | 4037 return false; |
| 4038 } | 4038 } |
| 4039 const intptr_t saved_pos = token_index_; | 4039 const intptr_t saved_pos = token_index_; |
| 4040 bool is_function_literal = false; | 4040 bool is_function_literal = false; |
| 4041 if ((CurrentToken() == Token::kIDENT) && | 4041 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4042 (LookaheadToken(1) == Token::kLPAREN)) { | |
| 4043 ConsumeToken(); // Consume function identifier. | 4042 ConsumeToken(); // Consume function identifier. |
| 4044 } else if (IsReturnType()) { | 4043 } else if (IsReturnType()) { |
| 4045 if (CurrentToken() != Token::kIDENT) { | 4044 if (!IsIdentifier()) { |
| 4046 SetPosition(saved_pos); | 4045 SetPosition(saved_pos); |
| 4047 return false; | 4046 return false; |
| 4048 } | 4047 } |
| 4049 ConsumeToken(); // Comsume function identifier. | 4048 ConsumeToken(); // Comsume function identifier. |
| 4050 } | 4049 } |
| 4051 if (CurrentToken() == Token::kLPAREN) { | 4050 if (CurrentToken() == Token::kLPAREN) { |
| 4052 SkipToMatchingParenthesis(); | 4051 SkipToMatchingParenthesis(); |
| 4053 if ((CurrentToken() == Token::kLBRACE) || | 4052 if ((CurrentToken() == Token::kLBRACE) || |
| 4054 (CurrentToken() == Token::kARROW)) { | 4053 (CurrentToken() == Token::kARROW)) { |
| 4055 is_function_literal = true; | 4054 is_function_literal = true; |
| 4056 } | 4055 } |
| 4057 } | 4056 } |
| 4058 SetPosition(saved_pos); | 4057 SetPosition(saved_pos); |
| 4059 return is_function_literal; | 4058 return is_function_literal; |
| 4060 } | 4059 } |
| 4061 | 4060 |
| 4062 | 4061 |
| 4063 // Current token position is the token after the opening ( of the for | 4062 // Current token position is the token after the opening ( of the for |
| 4064 // statement. Returns true if we recognize a for ( .. in expr) | 4063 // statement. Returns true if we recognize a for ( .. in expr) |
| 4065 // statement. | 4064 // statement. |
| 4066 bool Parser::IsForInStatement() { | 4065 bool Parser::IsForInStatement() { |
| 4067 const intptr_t saved_pos = token_index_; | 4066 const intptr_t saved_pos = token_index_; |
| 4068 bool result = false; | 4067 bool result = false; |
| 4069 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { | 4068 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { |
| 4070 ConsumeToken(); | 4069 ConsumeToken(); |
| 4071 } | 4070 } |
| 4072 if (CurrentToken() == Token::kIDENT) { | 4071 if (IsIdentifier()) { |
| 4073 if (LookaheadToken(1) == Token::kIN) { | 4072 if (LookaheadToken(1) == Token::kIN) { |
| 4074 result = true; | 4073 result = true; |
| 4075 } else if (IsOptionalType()) { | 4074 } else if (IsOptionalType()) { |
| 4076 if (CurrentToken() == Token::kIDENT) { | 4075 if (IsIdentifier()) { |
| 4077 ConsumeToken(); | 4076 ConsumeToken(); |
| 4078 } | 4077 } |
| 4079 result = (CurrentToken() == Token::kIN); | 4078 result = (CurrentToken() == Token::kIN); |
| 4080 } | 4079 } |
| 4081 } | 4080 } |
| 4082 SetPosition(saved_pos); | 4081 SetPosition(saved_pos); |
| 4083 return result; | 4082 return result; |
| 4084 } | 4083 } |
| 4085 | 4084 |
| 4086 | 4085 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4217 ExpectToken(Token::kCOLON); | 4216 ExpectToken(Token::kCOLON); |
| 4218 } | 4217 } |
| 4219 | 4218 |
| 4220 OpenBlock(); | 4219 OpenBlock(); |
| 4221 bool abrupt_completing_seen = false; | 4220 bool abrupt_completing_seen = false; |
| 4222 while (true) { | 4221 while (true) { |
| 4223 // Check whether the next statement still belongs to the current case | 4222 // Check whether the next statement still belongs to the current case |
| 4224 // clause. If we see 'case' or 'default', optionally preceeded by | 4223 // clause. If we see 'case' or 'default', optionally preceeded by |
| 4225 // a label, or closing brace, we stop parsing statements. | 4224 // a label, or closing brace, we stop parsing statements. |
| 4226 Token::Kind next_token; | 4225 Token::Kind next_token; |
| 4227 if (CurrentToken() == Token::kIDENT && | 4226 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 4228 LookaheadToken(1) == Token::kCOLON) { | |
| 4229 next_token = LookaheadToken(2); | 4227 next_token = LookaheadToken(2); |
| 4230 } else { | 4228 } else { |
| 4231 next_token = CurrentToken(); | 4229 next_token = CurrentToken(); |
| 4232 } | 4230 } |
| 4233 if (next_token == Token::kRBRACE) { | 4231 if (next_token == Token::kRBRACE) { |
| 4234 // End of switch statement. | 4232 // End of switch statement. |
| 4235 break; | 4233 break; |
| 4236 } | 4234 } |
| 4237 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 4235 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
| 4238 // End of this case clause. If there is a possible fall-through to | 4236 // 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... | |
| 4291 current_block_->scope->AddVariable(temp_variable); | 4289 current_block_->scope->AddVariable(temp_variable); |
| 4292 AstNode* save_switch_expr = | 4290 AstNode* save_switch_expr = |
| 4293 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 4291 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
| 4294 current_block_->statements->Add(save_switch_expr); | 4292 current_block_->statements->Add(save_switch_expr); |
| 4295 | 4293 |
| 4296 // Parse case clauses | 4294 // Parse case clauses |
| 4297 bool default_seen = false; | 4295 bool default_seen = false; |
| 4298 while (true) { | 4296 while (true) { |
| 4299 // Check for statement label | 4297 // Check for statement label |
| 4300 SourceLabel* case_label = NULL; | 4298 SourceLabel* case_label = NULL; |
| 4301 if (CurrentToken() == Token::kIDENT && | 4299 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 4302 LookaheadToken(1) == Token::kCOLON) { | |
| 4303 // Case statements start with a label. | 4300 // Case statements start with a label. |
| 4304 String* label_name = CurrentLiteral(); | 4301 String* label_name = CurrentLiteral(); |
| 4305 const intptr_t label_pos = token_index_; | 4302 const intptr_t label_pos = token_index_; |
| 4306 ConsumeToken(); // Consume label identifier. | 4303 ConsumeToken(); // Consume label identifier. |
| 4307 ConsumeToken(); // Consume colon. | 4304 ConsumeToken(); // Consume colon. |
| 4308 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 4305 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 4309 if (case_label == NULL) { | 4306 if (case_label == NULL) { |
| 4310 // Label does not exist yet. Add it to scope of switch statement. | 4307 // Label does not exist yet. Add it to scope of switch statement. |
| 4311 case_label = | 4308 case_label = |
| 4312 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); | 4309 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4651 }; | 4648 }; |
| 4652 | 4649 |
| 4653 | 4650 |
| 4654 // Parse the parameter specified in the catch clause. | 4651 // Parse the parameter specified in the catch clause. |
| 4655 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { | 4652 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { |
| 4656 TRACE_PARSER("ParseCatchParameter"); | 4653 TRACE_PARSER("ParseCatchParameter"); |
| 4657 ASSERT(catch_param != NULL); | 4654 ASSERT(catch_param != NULL); |
| 4658 catch_param->is_final = (CurrentToken() == Token::kFINAL); | 4655 catch_param->is_final = (CurrentToken() == Token::kFINAL); |
| 4659 catch_param->type = &AbstractType::ZoneHandle( | 4656 catch_param->type = &AbstractType::ZoneHandle( |
| 4660 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4657 ParseFinalVarOrType(kIsMandatory, kMustResolve)); |
| 4661 if (CurrentToken() != Token::kIDENT) { | |
| 4662 ErrorMsg("identifier expected"); | |
| 4663 } | |
| 4664 catch_param->token_index = token_index_; | 4658 catch_param->token_index = token_index_; |
| 4665 catch_param->var = CurrentLiteral(); | 4659 catch_param->var = ExpectIdentifier("identifier expected"); |
| 4666 ConsumeToken(); | |
| 4667 } | 4660 } |
| 4668 | 4661 |
| 4669 | 4662 |
| 4670 // Populate local scope of the catch block with the catch parameters. | 4663 // Populate local scope of the catch block with the catch parameters. |
| 4671 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 4664 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
| 4672 const CatchParamDesc& stack_trace_param, | 4665 const CatchParamDesc& stack_trace_param, |
| 4673 LocalScope* scope) { | 4666 LocalScope* scope) { |
| 4674 ASSERT(exception_param.var != NULL); | 4667 ASSERT(exception_param.var != NULL); |
| 4675 LocalVariable* var = new LocalVariable(exception_param.token_index, | 4668 LocalVariable* var = new LocalVariable(exception_param.token_index, |
| 4676 *(exception_param.var), | 4669 *(exception_param.var), |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4991 return try_catch_node; | 4984 return try_catch_node; |
| 4992 } | 4985 } |
| 4993 | 4986 |
| 4994 | 4987 |
| 4995 AstNode* Parser::ParseJump(String* label_name) { | 4988 AstNode* Parser::ParseJump(String* label_name) { |
| 4996 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 4989 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 4997 Token::Kind jump_kind = CurrentToken(); | 4990 Token::Kind jump_kind = CurrentToken(); |
| 4998 const intptr_t jump_pos = token_index_; | 4991 const intptr_t jump_pos = token_index_; |
| 4999 SourceLabel* target = NULL; | 4992 SourceLabel* target = NULL; |
| 5000 ConsumeToken(); | 4993 ConsumeToken(); |
| 5001 if (CurrentToken() == Token::kIDENT) { | 4994 if (IsIdentifier()) { |
| 5002 // Explicit label after break/continue. | 4995 // Explicit label after break/continue. |
| 5003 const String& target_name = *CurrentLiteral(); | 4996 const String& target_name = *CurrentLiteral(); |
| 5004 ConsumeToken(); | 4997 ConsumeToken(); |
| 5005 // Handle pathological cases first. | 4998 // Handle pathological cases first. |
| 5006 if (label_name != NULL && target_name.Equals(*label_name)) { | 4999 if (label_name != NULL && target_name.Equals(*label_name)) { |
| 5007 if (jump_kind == Token::kCONTINUE) { | 5000 if (jump_kind == Token::kCONTINUE) { |
| 5008 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 5001 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", |
| 5009 target_name.ToCString()); | 5002 target_name.ToCString()); |
| 5010 } | 5003 } |
| 5011 // L: break L; is a no-op. | 5004 // L: break L; is a no-op. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5047 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); | 5040 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); |
| 5048 } | 5041 } |
| 5049 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 5042 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 5050 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 5043 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
| 5051 Token::Str(jump_kind)); | 5044 Token::Str(jump_kind)); |
| 5052 } | 5045 } |
| 5053 return new JumpNode(jump_pos, jump_kind, target); | 5046 return new JumpNode(jump_pos, jump_kind, target); |
| 5054 } | 5047 } |
| 5055 | 5048 |
| 5056 | 5049 |
| 5050 bool Parser::IsDefinedInLexicalScope(const String& ident) { | |
| 5051 if (ResolveIdentInLocalScope(token_index_, ident, NULL)) { | |
| 5052 return true; | |
| 5053 } | |
| 5054 Object& obj = Object::Handle(); | |
| 5055 obj = library_.LookupObject(ident); | |
| 5056 return !obj.IsNull(); | |
| 5057 } | |
| 5058 | |
| 5059 | |
| 5057 AstNode* Parser::ParseStatement() { | 5060 AstNode* Parser::ParseStatement() { |
| 5058 TRACE_PARSER("ParseStatement"); | 5061 TRACE_PARSER("ParseStatement"); |
| 5059 AstNode* statement = NULL; | 5062 AstNode* statement = NULL; |
| 5060 intptr_t label_pos = 0; | 5063 intptr_t label_pos = 0; |
| 5061 String* label_name = NULL; | 5064 String* label_name = NULL; |
| 5062 if (CurrentToken() == Token::kIDENT) { | 5065 if (IsIdentifier()) { |
| 5063 if (LookaheadToken(1) == Token::kCOLON) { | 5066 if (LookaheadToken(1) == Token::kCOLON) { |
| 5064 // Statement starts with a label. | 5067 // Statement starts with a label. |
| 5065 label_name = CurrentLiteral(); | 5068 label_name = CurrentLiteral(); |
| 5066 label_pos = token_index_; | 5069 label_pos = token_index_; |
| 5067 ASSERT(label_pos > 0); | 5070 ASSERT(label_pos > 0); |
| 5068 ConsumeToken(); // Consume identifier. | 5071 ConsumeToken(); // Consume identifier. |
| 5069 ConsumeToken(); // Consume colon. | 5072 ConsumeToken(); // Consume colon. |
| 5070 } | 5073 } |
| 5071 } | 5074 } |
| 5072 const intptr_t statement_pos = token_index_; | 5075 const intptr_t statement_pos = token_index_; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 5091 } | 5094 } |
| 5092 AstNode* expr = ParseExpr(kAllowConst); | 5095 AstNode* expr = ParseExpr(kAllowConst); |
| 5093 statement = new ReturnNode(statement_pos, expr); | 5096 statement = new ReturnNode(statement_pos, expr); |
| 5094 } else { | 5097 } else { |
| 5095 statement = new ReturnNode(statement_pos); | 5098 statement = new ReturnNode(statement_pos); |
| 5096 } | 5099 } |
| 5097 AddNodeForFinallyInlining(statement); | 5100 AddNodeForFinallyInlining(statement); |
| 5098 ExpectSemicolon(); | 5101 ExpectSemicolon(); |
| 5099 } else if (CurrentToken() == Token::kIF) { | 5102 } else if (CurrentToken() == Token::kIF) { |
| 5100 statement = ParseIfStatement(label_name); | 5103 statement = ParseIfStatement(label_name); |
| 5101 } else if (CurrentToken() == Token::kASSERT) { | 5104 } else if ((CurrentToken() == Token::kASSERT) && |
| 5105 !IsDefinedInLexicalScope(*CurrentLiteral())) { | |
| 5102 statement = ParseAssertStatement(); | 5106 statement = ParseAssertStatement(); |
| 5103 ExpectSemicolon(); | 5107 ExpectSemicolon(); |
| 5104 } else if (IsVariableDeclaration()) { | 5108 } else if (IsVariableDeclaration()) { |
| 5105 statement = ParseVariableDeclarationList(); | 5109 statement = ParseVariableDeclarationList(); |
| 5106 ExpectSemicolon(); | 5110 ExpectSemicolon(); |
| 5107 } else if (IsFunctionDeclaration()) { | 5111 } else if (IsFunctionDeclaration()) { |
| 5108 statement = ParseFunctionStatement(false); | 5112 statement = ParseFunctionStatement(false); |
| 5109 } else if (CurrentToken() == Token::kLBRACE) { | 5113 } else if (CurrentToken() == Token::kLBRACE) { |
| 5110 SourceLabel* label = NULL; | 5114 SourceLabel* label = NULL; |
| 5111 OpenBlock(); | 5115 OpenBlock(); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5317 } | 5321 } |
| 5318 | 5322 |
| 5319 | 5323 |
| 5320 void Parser::UnexpectedToken() { | 5324 void Parser::UnexpectedToken() { |
| 5321 ErrorMsg("unexpected token '%s'", | 5325 ErrorMsg("unexpected token '%s'", |
| 5322 CurrentToken() == Token::kIDENT ? | 5326 CurrentToken() == Token::kIDENT ? |
| 5323 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 5327 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); |
| 5324 } | 5328 } |
| 5325 | 5329 |
| 5326 | 5330 |
| 5327 String* Parser::ExpectIdentifier(const char* msg) { | 5331 String* Parser::ExpectTypeIdentifier(const char* msg) { |
| 5328 if (CurrentToken() != Token::kIDENT) { | 5332 if (CurrentToken() != Token::kIDENT) { |
| 5329 ErrorMsg(msg); | 5333 ErrorMsg(msg); |
| 5330 } | 5334 } |
| 5331 String* ident = CurrentLiteral(); | 5335 String* ident = CurrentLiteral(); |
| 5332 ConsumeToken(); | 5336 ConsumeToken(); |
| 5333 return ident; | 5337 return ident; |
| 5334 } | 5338 } |
| 5335 | 5339 |
| 5340 // Check whether current token is an identifier or a built-in identifier. | |
| 5341 String* Parser::ExpectIdentifier(const char* msg) { | |
| 5342 if (CurrentToken() != Token::kIDENT && | |
| 5343 !Token::IsPseudoKeyword(CurrentToken())) { | |
|
siva
2012/01/13 18:48:20
Why not
if (!IsIdentifier()) {
ErrorMsg(msg);
}
hausner
2012/01/13 19:22:47
Excellent idea. I introduced IsIdentifier after I
| |
| 5344 ErrorMsg(msg); | |
| 5345 } | |
| 5346 String* ident = CurrentLiteral(); | |
| 5347 ConsumeToken(); | |
| 5348 return ident; | |
| 5349 } | |
| 5350 | |
| 5336 | 5351 |
| 5337 bool Parser::IsLiteral(const char* literal) { | 5352 bool Parser::IsLiteral(const char* literal) { |
| 5338 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); | 5353 const uint8_t* characters = reinterpret_cast<const uint8_t*>(literal); |
| 5339 intptr_t len = strlen(literal); | 5354 intptr_t len = strlen(literal); |
| 5340 return (CurrentToken() == Token::kIDENT) | 5355 return IsIdentifier() && CurrentLiteral()->Equals(characters, len); |
| 5341 && CurrentLiteral()->Equals(characters, len); | |
| 5342 } | 5356 } |
| 5343 | 5357 |
| 5344 | 5358 |
| 5345 bool Parser::IsIncrementOperator(Token::Kind token) { | 5359 bool Parser::IsIncrementOperator(Token::Kind token) { |
| 5346 return token == Token::kINCR || token == Token::kDECR; | 5360 return token == Token::kINCR || token == Token::kDECR; |
| 5347 } | 5361 } |
| 5348 | 5362 |
| 5349 | 5363 |
| 5350 bool Parser::IsPrefixOperator(Token::Kind token) { | 5364 bool Parser::IsPrefixOperator(Token::Kind token) { |
| 5351 return token == Token::kADD || token == Token::kSUB | 5365 return token == Token::kADD || token == Token::kSUB |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5709 } else { | 5723 } else { |
| 5710 arguments = implicit_arguments; | 5724 arguments = implicit_arguments; |
| 5711 } | 5725 } |
| 5712 GrowableArray<const String*> names; | 5726 GrowableArray<const String*> names; |
| 5713 bool named_argument_seen = false; | 5727 bool named_argument_seen = false; |
| 5714 if (LookaheadToken(1) != Token::kRPAREN) { | 5728 if (LookaheadToken(1) != Token::kRPAREN) { |
| 5715 do { | 5729 do { |
| 5716 ASSERT((CurrentToken() == Token::kLPAREN) || | 5730 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 5717 (CurrentToken() == Token::kCOMMA)); | 5731 (CurrentToken() == Token::kCOMMA)); |
| 5718 ConsumeToken(); | 5732 ConsumeToken(); |
| 5719 if ((CurrentToken() == Token::kIDENT) && | 5733 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 5720 (LookaheadToken(1) == Token::kCOLON)) { | |
| 5721 named_argument_seen = true; | 5734 named_argument_seen = true; |
| 5722 // The canonicalization of the argument descriptor array built in the | 5735 // The canonicalization of the argument descriptor array built in the |
| 5723 // code generator requires that the names are symbols, i.e. | 5736 // code generator requires that the names are symbols, i.e. |
| 5724 // canonicalized strings. | 5737 // canonicalized strings. |
| 5725 ASSERT(CurrentLiteral()->IsSymbol()); | 5738 ASSERT(CurrentLiteral()->IsSymbol()); |
| 5726 for (int i = 0; i < names.length(); i++) { | 5739 for (int i = 0; i < names.length(); i++) { |
| 5727 if (CurrentLiteral()->Equals(*names[i])) { | 5740 if (CurrentLiteral()->Equals(*names[i])) { |
| 5728 ErrorMsg("duplicate named argument"); | 5741 ErrorMsg("duplicate named argument"); |
| 5729 } | 5742 } |
| 5730 } | 5743 } |
| (...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7094 return constructor_name; | 7107 return constructor_name; |
| 7095 } | 7108 } |
| 7096 | 7109 |
| 7097 | 7110 |
| 7098 AstNode* Parser::ParseNewOperator() { | 7111 AstNode* Parser::ParseNewOperator() { |
| 7099 TRACE_PARSER("ParseNewOperator"); | 7112 TRACE_PARSER("ParseNewOperator"); |
| 7100 const intptr_t new_pos = token_index_; | 7113 const intptr_t new_pos = token_index_; |
| 7101 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); | 7114 ASSERT((CurrentToken() == Token::kNEW) || (CurrentToken() == Token::kCONST)); |
| 7102 bool is_const = (CurrentToken() == Token::kCONST); | 7115 bool is_const = (CurrentToken() == Token::kCONST); |
| 7103 ConsumeToken(); | 7116 ConsumeToken(); |
| 7104 if (CurrentToken() != Token::kIDENT) { | 7117 if (!IsIdentifier()) { |
| 7105 ErrorMsg("type name expected"); | 7118 ErrorMsg("type name expected"); |
| 7106 } | 7119 } |
| 7107 | 7120 |
| 7108 // The grammar allows for an optional ('.' identifier)?, which is a named | 7121 // The grammar allows for an optional ('.' identifier)?, which is a named |
| 7109 // constructor. For that reason, we cannot unconditionally call | 7122 // constructor. For that reason, we cannot unconditionally call |
| 7110 // ParseType(kMustResolve) after we see an identifier, because the named | 7123 // ParseType(kMustResolve) after we see an identifier, because the named |
| 7111 // constructor would be misinterpreted as a qualified type name. | 7124 // constructor would be misinterpreted as a qualified type name. |
| 7112 // TODO(regis): Revisit once we correctly support qualified identifiers. | 7125 // TODO(regis): Revisit once we correctly support qualified identifiers. |
| 7113 // For now, we inline a customized version of ParseType(kMustResolve). | 7126 // For now, we inline a customized version of ParseType(kMustResolve). |
| 7114 const intptr_t type_pos = token_index_; | 7127 const intptr_t type_pos = token_index_; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7355 | 7368 |
| 7356 AstNode* Parser::ParsePrimary() { | 7369 AstNode* Parser::ParsePrimary() { |
| 7357 TRACE_PARSER("ParsePrimary"); | 7370 TRACE_PARSER("ParsePrimary"); |
| 7358 AstNode* primary = NULL; | 7371 AstNode* primary = NULL; |
| 7359 if (IsFunctionLiteral()) { | 7372 if (IsFunctionLiteral()) { |
| 7360 // The name of a literal function is visible from inside the function, but | 7373 // The name of a literal function is visible from inside the function, but |
| 7361 // must not collide with names in the scope declaring the literal. | 7374 // must not collide with names in the scope declaring the literal. |
| 7362 OpenBlock(); | 7375 OpenBlock(); |
| 7363 primary = ParseFunctionStatement(true); | 7376 primary = ParseFunctionStatement(true); |
| 7364 CloseBlock(); | 7377 CloseBlock(); |
| 7365 } else if (CurrentToken() == Token::kIDENT) { | 7378 } else if (IsIdentifier()) { |
| 7366 QualIdent qual_ident; | 7379 QualIdent qual_ident; |
| 7367 ParseQualIdent(&qual_ident); | 7380 ParseQualIdent(&qual_ident); |
| 7368 if (qual_ident.is_local_scope_ident) { | 7381 if (qual_ident.is_local_scope_ident) { |
| 7369 ResolveIdentInLocalScope(qual_ident.ident_pos, | 7382 ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 7370 *qual_ident.ident, | 7383 *qual_ident.ident, |
| 7371 &primary); | 7384 &primary); |
| 7372 } else { | 7385 } else { |
| 7373 if (qual_ident.qualifier == NULL) { | 7386 if (qual_ident.qualifier == NULL) { |
| 7374 // This is an unqualified identifier so resolve the identifier | 7387 // This is an unqualified identifier so resolve the identifier |
| 7375 // locally in the main app library and all libraries imported by it. | 7388 // 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... | |
| 7491 Instance& value = Instance::ZoneHandle(Compiler::ExecuteOnce(seq)); | 7504 Instance& value = Instance::ZoneHandle(Compiler::ExecuteOnce(seq)); |
| 7492 if (value.IsNull()) { | 7505 if (value.IsNull()) { |
| 7493 value ^= value.Canonicalize(); | 7506 value ^= value.Canonicalize(); |
| 7494 } | 7507 } |
| 7495 return value; | 7508 return value; |
| 7496 } | 7509 } |
| 7497 } | 7510 } |
| 7498 | 7511 |
| 7499 | 7512 |
| 7500 void Parser::SkipFunctionLiteral() { | 7513 void Parser::SkipFunctionLiteral() { |
| 7501 if (CurrentToken() == Token::kIDENT) { | 7514 if (IsIdentifier()) { |
| 7502 if (LookaheadToken(1) != Token::kLPAREN) { | 7515 if (LookaheadToken(1) != Token::kLPAREN) { |
| 7503 SkipType(true); | 7516 SkipType(true); |
| 7504 } | 7517 } |
| 7505 ExpectIdentifier("function name expected"); | 7518 ExpectIdentifier("function name expected"); |
| 7506 } | 7519 } |
| 7507 if (CurrentToken() == Token::kLPAREN) { | 7520 if (CurrentToken() == Token::kLPAREN) { |
| 7508 const bool allow_explicit_default_values = true; | 7521 const bool allow_explicit_default_values = true; |
| 7509 ParamList ignore_params; | 7522 ParamList ignore_params; |
| 7510 ParseFormalParameterList(allow_explicit_default_values, &ignore_params); | 7523 ParseFormalParameterList(allow_explicit_default_values, &ignore_params); |
| 7511 } | 7524 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7569 (CurrentToken() == Token::kINDEX)) { | 7582 (CurrentToken() == Token::kINDEX)) { |
| 7570 SkipListLiteral(); | 7583 SkipListLiteral(); |
| 7571 } else if (CurrentToken() == Token::kLBRACE) { | 7584 } else if (CurrentToken() == Token::kLBRACE) { |
| 7572 SkipMapLiteral(); | 7585 SkipMapLiteral(); |
| 7573 } | 7586 } |
| 7574 } | 7587 } |
| 7575 | 7588 |
| 7576 | 7589 |
| 7577 void Parser::SkipNewOperator() { | 7590 void Parser::SkipNewOperator() { |
| 7578 ConsumeToken(); // Skip new or const keyword. | 7591 ConsumeToken(); // Skip new or const keyword. |
| 7579 if (CurrentToken() == Token::kIDENT) { | 7592 if (IsIdentifier()) { |
| 7580 SkipType(false); | 7593 SkipType(false); |
| 7581 if (CurrentToken() == Token::kLPAREN) { | 7594 if (CurrentToken() == Token::kLPAREN) { |
| 7582 SkipActualParameters(); | 7595 SkipActualParameters(); |
| 7583 return; | 7596 return; |
| 7584 } | 7597 } |
| 7585 } | 7598 } |
| 7586 } | 7599 } |
| 7587 | 7600 |
| 7588 | 7601 |
| 7589 void Parser::SkipStringLiteral() { | 7602 void Parser::SkipStringLiteral() { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7649 SkipNewOperator(); | 7662 SkipNewOperator(); |
| 7650 } | 7663 } |
| 7651 break; | 7664 break; |
| 7652 case Token::kLT: | 7665 case Token::kLT: |
| 7653 case Token::kLBRACE: | 7666 case Token::kLBRACE: |
| 7654 case Token::kLBRACK: | 7667 case Token::kLBRACK: |
| 7655 case Token::kINDEX: | 7668 case Token::kINDEX: |
| 7656 SkipCompoundLiteral(); | 7669 SkipCompoundLiteral(); |
| 7657 break; | 7670 break; |
| 7658 default: | 7671 default: |
| 7659 UnexpectedToken(); | 7672 if (IsIdentifier()) { |
| 7660 UNREACHABLE(); | 7673 ConsumeToken(); // Handle pseudo-keyword identifiers. |
| 7674 } else { | |
| 7675 UnexpectedToken(); | |
| 7676 UNREACHABLE(); | |
| 7677 } | |
| 7661 break; | 7678 break; |
| 7662 } | 7679 } |
| 7663 } | 7680 } |
| 7664 | 7681 |
| 7665 | 7682 |
| 7666 void Parser::SkipPostfixExpr() { | 7683 void Parser::SkipPostfixExpr() { |
| 7667 SkipPrimary(); | 7684 SkipPrimary(); |
| 7668 while (true) { | 7685 while (true) { |
| 7669 if (CurrentToken() == Token::kPERIOD) { | 7686 if (CurrentToken() == Token::kPERIOD) { |
| 7670 ConsumeToken(); | 7687 ConsumeToken(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7726 } | 7743 } |
| 7727 | 7744 |
| 7728 | 7745 |
| 7729 void Parser::SkipNestedExpr() { | 7746 void Parser::SkipNestedExpr() { |
| 7730 const bool saved_mode = SetAllowFunctionLiterals(true); | 7747 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7731 SkipExpr(); | 7748 SkipExpr(); |
| 7732 SetAllowFunctionLiterals(saved_mode); | 7749 SetAllowFunctionLiterals(saved_mode); |
| 7733 } | 7750 } |
| 7734 | 7751 |
| 7735 } // namespace dart | 7752 } // namespace dart |
| OLD | NEW |