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

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
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)) {
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
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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/token.h » ('j') | tests/language/src/NamingTest.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698