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

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

Issue 9107070: Proper handling of built-in identifiers (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/token.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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
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
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(&params, current_block_->scope); 634 AddFormalParamsToScope(&params, 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
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(&params, current_block_->scope); 670 AddFormalParamsToScope(&params, 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698