| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/flags.h" | 13 #include "vm/flags.h" |
| 14 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 15 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
| 16 #include "vm/native_entry.h" | 16 #include "vm/native_entry.h" |
| 17 #include "vm/object.h" | 17 #include "vm/object.h" |
| 18 #include "vm/object_store.h" | 18 #include "vm/object_store.h" |
| 19 #include "vm/resolver.h" | 19 #include "vm/resolver.h" |
| 20 #include "vm/scopes.h" | 20 #include "vm/scopes.h" |
| 21 | 21 |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 24 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 25 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 25 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 26 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 26 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 27 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 27 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
| 28 DEFINE_FLAG(bool, silent_warnings, true, "Silence warnings."); | 28 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
| 29 | 29 |
| 30 // All references to Dart names are listed here. | 30 // All references to Dart names are listed here. |
| 31 static const char* kAssertionErrorName = "AssertionError"; | 31 static const char* kAssertionErrorName = "AssertionError"; |
| 32 static const char* kFallThroughErrorName = "FallThroughError"; | 32 static const char* kFallThroughErrorName = "FallThroughError"; |
| 33 static const char* kThrowNewName = "throwNew"; | 33 static const char* kThrowNewName = "throwNew"; |
| 34 static const char* kGrowableObjectArrayFromArrayName = | 34 static const char* kGrowableObjectArrayFromArrayName = |
| 35 "GrowableObjectArray._usingArray"; | 35 "GrowableObjectArray._usingArray"; |
| 36 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; | 36 static const char* kGrowableObjectArrayName = "GrowableObjectArray"; |
| 37 static const char* kMutableMapName = "MutableMap"; | 37 static const char* kMutableMapName = "MutableMap"; |
| 38 static const char* kMutableMapFromLiteralName = "fromLiteral"; | 38 static const char* kMutableMapFromLiteralName = "fromLiteral"; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 return &result; | 273 return &result; |
| 274 } | 274 } |
| 275 | 275 |
| 276 | 276 |
| 277 // A QualIdent is an optionally qualified identifier. | 277 // A QualIdent is an optionally qualified identifier. |
| 278 struct QualIdent { | 278 struct QualIdent { |
| 279 QualIdent() { | 279 QualIdent() { |
| 280 Clear(); | 280 Clear(); |
| 281 } | 281 } |
| 282 void Clear() { | 282 void Clear() { |
| 283 local_scope_ident = false; | 283 is_local_scope_ident = false; |
| 284 lib_prefix = NULL; | 284 lib_prefix = NULL; |
| 285 qualifier = NULL; | 285 qualifier = NULL; |
| 286 ident_pos = 0; | 286 ident_pos = 0; |
| 287 ident = NULL; | 287 ident = NULL; |
| 288 } | 288 } |
| 289 bool local_scope_ident; | 289 bool is_local_scope_ident; |
| 290 LibraryPrefix* lib_prefix; | 290 LibraryPrefix* lib_prefix; |
| 291 String* qualifier; | 291 String* qualifier; |
| 292 intptr_t ident_pos; | 292 intptr_t ident_pos; |
| 293 String* ident; | 293 String* ident; |
| 294 }; | 294 }; |
| 295 | 295 |
| 296 | 296 |
| 297 struct ParamDesc { | 297 struct ParamDesc { |
| 298 ParamDesc() | 298 ParamDesc() |
| 299 : type(NULL), | 299 : type(NULL), |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 CompilerStats::parser_timer.Start(); | 565 CompilerStats::parser_timer.Start(); |
| 566 } | 566 } |
| 567 SequenceNode* node_sequence = NULL; | 567 SequenceNode* node_sequence = NULL; |
| 568 Array& default_parameter_values = Array::Handle(); | 568 Array& default_parameter_values = Array::Handle(); |
| 569 switch (func.kind()) { | 569 switch (func.kind()) { |
| 570 case RawFunction::kFunction: | 570 case RawFunction::kFunction: |
| 571 case RawFunction::kClosureFunction: | 571 case RawFunction::kClosureFunction: |
| 572 case RawFunction::kGetterFunction: | 572 case RawFunction::kGetterFunction: |
| 573 case RawFunction::kSetterFunction: | 573 case RawFunction::kSetterFunction: |
| 574 case RawFunction::kConstructor: | 574 case RawFunction::kConstructor: |
| 575 ASSERT(!func.IsFactory() || (func.signature_class() != Class::null())); |
| 575 node_sequence = parser.ParseFunc(func, default_parameter_values); | 576 node_sequence = parser.ParseFunc(func, default_parameter_values); |
| 576 break; | 577 break; |
| 577 case RawFunction::kImplicitGetter: | 578 case RawFunction::kImplicitGetter: |
| 578 ASSERT(!func.is_static()); | 579 ASSERT(!func.is_static()); |
| 579 node_sequence = parser.ParseInstanceGetter(func); | 580 node_sequence = parser.ParseInstanceGetter(func); |
| 580 break; | 581 break; |
| 581 case RawFunction::kImplicitSetter: | 582 case RawFunction::kImplicitSetter: |
| 582 ASSERT(!func.is_static()); | 583 ASSERT(!func.is_static()); |
| 583 node_sequence = parser.ParseInstanceSetter(func); | 584 node_sequence = parser.ParseInstanceSetter(func); |
| 584 break; | 585 break; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 | 635 |
| 635 // Static const fields must have an initializer. | 636 // Static const fields must have an initializer. |
| 636 ExpectToken(Token::kIDENT); | 637 ExpectToken(Token::kIDENT); |
| 637 ExpectToken(Token::kASSIGN); | 638 ExpectToken(Token::kASSIGN); |
| 638 | 639 |
| 639 // 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 |
| 640 // the constant folding code to create, compile and execute a code | 641 // the constant folding code to create, compile and execute a code |
| 641 // fragment to evaluate the expression. Instead, we just make sure | 642 // fragment to evaluate the expression. Instead, we just make sure |
| 642 // the static const field initializer is a constant expression and | 643 // the static const field initializer is a constant expression and |
| 643 // leave the evaluation to the getter function. | 644 // leave the evaluation to the getter function. |
| 644 intptr_t expr_pos = token_index_; | 645 const intptr_t expr_pos = token_index_; |
| 645 AstNode* expr = ParseExpr(kAllowConst); | 646 AstNode* expr = ParseExpr(kAllowConst); |
| 646 if (expr->EvalConstExpr() == NULL) { | 647 if (expr->EvalConstExpr() == NULL) { |
| 647 ErrorMsg(expr_pos, "initializer must be a compile time constant"); | 648 ErrorMsg(expr_pos, "initializer must be a compile time constant"); |
| 648 } | 649 } |
| 649 ReturnNode* return_node = new ReturnNode(token_index_, expr); | 650 ReturnNode* return_node = new ReturnNode(token_index_, expr); |
| 650 current_block_->statements->Add(return_node); | 651 current_block_->statements->Add(return_node); |
| 651 return CloseBlock(); | 652 return CloseBlock(); |
| 652 } | 653 } |
| 653 | 654 |
| 654 | 655 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 | 725 |
| 725 current_block_->statements->Add(store_field); | 726 current_block_->statements->Add(store_field); |
| 726 current_block_->statements->Add(new ReturnNode(token_index_)); | 727 current_block_->statements->Add(new ReturnNode(token_index_)); |
| 727 return CloseBlock(); | 728 return CloseBlock(); |
| 728 } | 729 } |
| 729 | 730 |
| 730 | 731 |
| 731 void Parser::SkipBlock() { | 732 void Parser::SkipBlock() { |
| 732 ASSERT(CurrentToken() == Token::kLBRACE); | 733 ASSERT(CurrentToken() == Token::kLBRACE); |
| 733 GrowableArray<Token::Kind> token_stack(8); | 734 GrowableArray<Token::Kind> token_stack(8); |
| 734 intptr_t block_start_pos = token_index_; | 735 const intptr_t block_start_pos = token_index_; |
| 735 bool is_match = true; | 736 bool is_match = true; |
| 736 bool unexpected_token_found = false; | 737 bool unexpected_token_found = false; |
| 737 Token::Kind token; | 738 Token::Kind token; |
| 738 intptr_t token_index; | 739 intptr_t token_index; |
| 739 do { | 740 do { |
| 740 token = CurrentToken(); | 741 token = CurrentToken(); |
| 741 token_index = token_index_; | 742 token_index = token_index_; |
| 742 switch (token) { | 743 switch (token) { |
| 743 case Token::kLBRACE: | 744 case Token::kLBRACE: |
| 744 case Token::kLPAREN: | 745 case Token::kLPAREN: |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 struct FieldInitExpression { | 1366 struct FieldInitExpression { |
| 1366 Field* inst_field; | 1367 Field* inst_field; |
| 1367 AstNode* expr; | 1368 AstNode* expr; |
| 1368 }; | 1369 }; |
| 1369 | 1370 |
| 1370 | 1371 |
| 1371 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1372 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 1372 GrowableArray<FieldInitExpression>* initializers) { | 1373 GrowableArray<FieldInitExpression>* initializers) { |
| 1373 const Array& fields = Array::Handle(cls.fields()); | 1374 const Array& fields = Array::Handle(cls.fields()); |
| 1374 Field& f = Field::Handle(); | 1375 Field& f = Field::Handle(); |
| 1375 intptr_t saved_pos = token_index_; | 1376 const intptr_t saved_pos = token_index_; |
| 1376 for (int i = 0; i < fields.Length(); i++) { | 1377 for (int i = 0; i < fields.Length(); i++) { |
| 1377 f ^= fields.At(i); | 1378 f ^= fields.At(i); |
| 1378 if (!f.is_static() && f.has_initializer()) { | 1379 if (!f.is_static() && f.has_initializer()) { |
| 1379 Field& field = Field::ZoneHandle(); | 1380 Field& field = Field::ZoneHandle(); |
| 1380 field ^= fields.At(i); | 1381 field ^= fields.At(i); |
| 1381 intptr_t field_pos = field.token_index(); | 1382 intptr_t field_pos = field.token_index(); |
| 1382 SetPosition(field_pos); | 1383 SetPosition(field_pos); |
| 1383 ASSERT(CurrentToken() == Token::kIDENT); | 1384 ASSERT(CurrentToken() == Token::kIDENT); |
| 1384 ConsumeToken(); | 1385 ConsumeToken(); |
| 1385 ExpectToken(Token::kASSIGN); | 1386 ExpectToken(Token::kASSIGN); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1409 // guarantee that. | 1410 // guarantee that. |
| 1410 ConsumeToken(); // Colon. | 1411 ConsumeToken(); // Colon. |
| 1411 ParseConstructorRedirection(cls, receiver); | 1412 ParseConstructorRedirection(cls, receiver); |
| 1412 return; | 1413 return; |
| 1413 } | 1414 } |
| 1414 do { | 1415 do { |
| 1415 ConsumeToken(); // Colon or comma. | 1416 ConsumeToken(); // Colon or comma. |
| 1416 AstNode* init_statement; | 1417 AstNode* init_statement; |
| 1417 if (CurrentToken() == Token::kSUPER) { | 1418 if (CurrentToken() == Token::kSUPER) { |
| 1418 if (super_init_seen) { | 1419 if (super_init_seen) { |
| 1419 ErrorMsg("Duplicate call to super constructor"); | 1420 ErrorMsg("duplicate call to super constructor"); |
| 1420 } | 1421 } |
| 1421 init_statement = ParseSuperInitializer(cls, receiver); | 1422 init_statement = ParseSuperInitializer(cls, receiver); |
| 1422 super_init_seen = true; | 1423 super_init_seen = true; |
| 1423 } else { | 1424 } else { |
| 1424 init_statement = ParseInitializer(cls, receiver); | 1425 init_statement = ParseInitializer(cls, receiver); |
| 1425 } | 1426 } |
| 1426 current_block_->statements->Add(init_statement); | 1427 current_block_->statements->Add(init_statement); |
| 1427 } while (CurrentToken() == Token::kCOMMA); | 1428 } while (CurrentToken() == Token::kCOMMA); |
| 1428 } | 1429 } |
| 1429 if (!super_init_seen) { | 1430 if (!super_init_seen) { |
| 1430 // Generate implicit super() if we haven't seen an explicit super call | 1431 // Generate implicit super() if we haven't seen an explicit super call |
| 1431 // or constructor redirection. | 1432 // or constructor redirection. |
| 1432 GenerateSuperConstructorCall(cls, receiver); | 1433 GenerateSuperConstructorCall(cls, receiver); |
| 1433 } | 1434 } |
| 1434 CheckConstFieldsInitialized(cls); | 1435 CheckConstFieldsInitialized(cls); |
| 1435 } | 1436 } |
| 1436 | 1437 |
| 1437 | 1438 |
| 1438 void Parser::ParseConstructorRedirection(const Class& cls, | 1439 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1439 LocalVariable* receiver) { | 1440 LocalVariable* receiver) { |
| 1440 ASSERT(CurrentToken() == Token::kTHIS); | 1441 ASSERT(CurrentToken() == Token::kTHIS); |
| 1441 intptr_t call_pos = token_index_; | 1442 const intptr_t call_pos = token_index_; |
| 1442 ConsumeToken(); | 1443 ConsumeToken(); |
| 1443 String& ctor_name = String::Handle(cls.Name()); | 1444 String& ctor_name = String::Handle(cls.Name()); |
| 1444 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1445 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1445 | 1446 |
| 1446 if (CurrentToken() == Token::kPERIOD) { | 1447 if (CurrentToken() == Token::kPERIOD) { |
| 1447 ConsumeToken(); | 1448 ConsumeToken(); |
| 1448 ctor_suffix = String::Concat( | 1449 ctor_suffix = String::Concat( |
| 1449 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1450 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| 1450 } | 1451 } |
| 1451 ctor_name = String::Concat(ctor_name, ctor_suffix); | 1452 ctor_name = String::Concat(ctor_name, ctor_suffix); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1474 ctor_name.ToCString()); | 1475 ctor_name.ToCString()); |
| 1475 } | 1476 } |
| 1476 CheckFunctionIsCallable(call_pos, redirect_ctor); | 1477 CheckFunctionIsCallable(call_pos, redirect_ctor); |
| 1477 current_block_->statements->Add( | 1478 current_block_->statements->Add( |
| 1478 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 1479 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 1479 } | 1480 } |
| 1480 | 1481 |
| 1481 | 1482 |
| 1482 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 1483 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 1483 ASSERT(func.IsConstructor()); | 1484 ASSERT(func.IsConstructor()); |
| 1484 intptr_t ctor_pos = token_index_; | 1485 const intptr_t ctor_pos = token_index_; |
| 1485 | 1486 |
| 1486 // Implicit 'this' is the only parameter/local variable. | 1487 // Implicit 'this' is the only parameter/local variable. |
| 1487 OpenFunctionBlock(func); | 1488 OpenFunctionBlock(func); |
| 1488 | 1489 |
| 1489 // Parse expressions of instance fields that have an explicit | 1490 // Parse expressions of instance fields that have an explicit |
| 1490 // initializers. | 1491 // initializers. |
| 1491 GrowableArray<FieldInitExpression> initializers; | 1492 GrowableArray<FieldInitExpression> initializers; |
| 1492 Class& cls = Class::Handle(func.owner()); | 1493 Class& cls = Class::Handle(func.owner()); |
| 1493 ParseInitializedInstanceFields(cls, &initializers); | 1494 ParseInitializedInstanceFields(cls, &initializers); |
| 1494 | 1495 |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 CaptureReceiver(); | 1837 CaptureReceiver(); |
| 1837 } | 1838 } |
| 1838 } | 1839 } |
| 1839 | 1840 |
| 1840 if (CurrentToken() == Token::kLBRACE) { | 1841 if (CurrentToken() == Token::kLBRACE) { |
| 1841 ConsumeToken(); | 1842 ConsumeToken(); |
| 1842 ParseStatementSequence(); | 1843 ParseStatementSequence(); |
| 1843 ExpectToken(Token::kRBRACE); | 1844 ExpectToken(Token::kRBRACE); |
| 1844 } else if (CurrentToken() == Token::kARROW) { | 1845 } else if (CurrentToken() == Token::kARROW) { |
| 1845 ConsumeToken(); | 1846 ConsumeToken(); |
| 1846 intptr_t expr_pos = token_index_; | 1847 const intptr_t expr_pos = token_index_; |
| 1847 AstNode* expr = ParseExpr(kAllowConst); | 1848 AstNode* expr = ParseExpr(kAllowConst); |
| 1848 ASSERT(expr != NULL); | 1849 ASSERT(expr != NULL); |
| 1849 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 1850 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 1850 } else if (IsLiteral("native")) { | 1851 } else if (IsLiteral("native")) { |
| 1851 ParseNativeFunctionBlock(¶ms, func); | 1852 ParseNativeFunctionBlock(¶ms, func); |
| 1852 } else { | 1853 } else { |
| 1853 UnexpectedToken(); | 1854 UnexpectedToken(); |
| 1854 } | 1855 } |
| 1855 | 1856 |
| 1856 SequenceNode* statements = CloseBlock(); | 1857 SequenceNode* statements = CloseBlock(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 SkipExpr(); | 1904 SkipExpr(); |
| 1904 SetAllowFunctionLiterals(true); | 1905 SetAllowFunctionLiterals(true); |
| 1905 } | 1906 } |
| 1906 } while (CurrentToken() == Token::kCOMMA); | 1907 } while (CurrentToken() == Token::kCOMMA); |
| 1907 } | 1908 } |
| 1908 | 1909 |
| 1909 | 1910 |
| 1910 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 1911 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
| 1911 ASSERT(CurrentToken() == Token::kIDENT); | 1912 ASSERT(CurrentToken() == Token::kIDENT); |
| 1912 if (!is_top_level_) { | 1913 if (!is_top_level_) { |
| 1913 bool local_ident = ResolveIdentInLocalScope(token_index_, | 1914 bool is_local_ident = ResolveIdentInLocalScope(token_index_, |
| 1914 *CurrentLiteral(), | 1915 *CurrentLiteral(), |
| 1915 NULL); | 1916 NULL); |
| 1916 qual_ident->ident_pos = token_index_; | 1917 qual_ident->ident_pos = token_index_; |
| 1917 qual_ident->ident = CurrentLiteral(); | 1918 qual_ident->ident = CurrentLiteral(); |
| 1918 qual_ident->lib_prefix = NULL; | 1919 qual_ident->lib_prefix = NULL; |
| 1919 qual_ident->qualifier = NULL; | 1920 qual_ident->qualifier = NULL; |
| 1920 qual_ident->local_scope_ident = local_ident; | 1921 qual_ident->is_local_scope_ident = is_local_ident; |
| 1921 ConsumeToken(); | 1922 ConsumeToken(); |
| 1922 if (!local_ident && (CurrentToken() == Token::kPERIOD)) { | 1923 if (!is_local_ident && (CurrentToken() == Token::kPERIOD)) { |
| 1923 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 1924 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 1924 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 1925 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 1925 if (!lib_prefix.IsNull()) { | 1926 if (!lib_prefix.IsNull()) { |
| 1926 // We have a library prefix qualified identifier. | 1927 // We have a library prefix qualified identifier. |
| 1927 ConsumeToken(); // Consume the kPERIOD token. | 1928 ConsumeToken(); // Consume the kPERIOD token. |
| 1928 qual_ident->lib_prefix = &lib_prefix; | 1929 qual_ident->lib_prefix = &lib_prefix; |
| 1929 qual_ident->qualifier = qual_ident->ident; | 1930 qual_ident->qualifier = qual_ident->ident; |
| 1930 qual_ident->ident_pos = token_index_; | 1931 qual_ident->ident_pos = token_index_; |
| 1931 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); | 1932 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); |
| 1932 } | 1933 } |
| 1933 } | 1934 } |
| 1934 } else { | 1935 } else { |
| 1935 qual_ident->ident_pos = token_index_; | 1936 qual_ident->ident_pos = token_index_; |
| 1936 qual_ident->ident = CurrentLiteral(); | 1937 qual_ident->ident = CurrentLiteral(); |
| 1937 qual_ident->lib_prefix = NULL; | 1938 qual_ident->lib_prefix = NULL; |
| 1938 qual_ident->qualifier = NULL; | 1939 qual_ident->qualifier = NULL; |
| 1939 qual_ident->local_scope_ident = false; | 1940 qual_ident->is_local_scope_ident = false; |
| 1940 ConsumeToken(); | 1941 ConsumeToken(); |
| 1941 if (CurrentToken() == Token::kPERIOD) { | 1942 if (CurrentToken() == Token::kPERIOD) { |
| 1942 ConsumeToken(); // Consume the kPERIOD token. | 1943 ConsumeToken(); // Consume the kPERIOD token. |
| 1943 qual_ident->qualifier = qual_ident->ident; | 1944 qual_ident->qualifier = qual_ident->ident; |
| 1944 qual_ident->ident_pos = token_index_; | 1945 qual_ident->ident_pos = token_index_; |
| 1945 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); | 1946 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); |
| 1946 } | 1947 } |
| 1947 } | 1948 } |
| 1948 } | 1949 } |
| 1949 | 1950 |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2284 ErrorMsg("identifier expected after 'final'"); | 2285 ErrorMsg("identifier expected after 'final'"); |
| 2285 } | 2286 } |
| 2286 ConsumeToken(); | 2287 ConsumeToken(); |
| 2287 member.has_var = true; | 2288 member.has_var = true; |
| 2288 // The member type is the 'Dynamic' type. | 2289 // The member type is the 'Dynamic' type. |
| 2289 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2290 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2290 } else if (CurrentToken() == Token::kFACTORY) { | 2291 } else if (CurrentToken() == Token::kFACTORY) { |
| 2291 ConsumeToken(); | 2292 ConsumeToken(); |
| 2292 member.has_factory = true; | 2293 member.has_factory = true; |
| 2293 member.has_static = true; | 2294 member.has_static = true; |
| 2294 // The member result type is the type of this class. | 2295 // The result type depends on the name of the factory method. |
| 2295 // TODO(regis): What are the type arguments? | |
| 2296 member.type = | |
| 2297 &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz()))); | |
| 2298 } | 2296 } |
| 2299 // Optionally parse a type. | 2297 // Optionally parse a type. |
| 2300 if (CurrentToken() == Token::kVOID) { | 2298 if (CurrentToken() == Token::kVOID) { |
| 2301 if (member.has_var || member.has_factory) { | 2299 if (member.has_var || member.has_factory) { |
| 2302 ErrorMsg("void not expected"); | 2300 ErrorMsg("void not expected"); |
| 2303 } | 2301 } |
| 2304 ConsumeToken(); | 2302 ConsumeToken(); |
| 2305 ASSERT(member.type == NULL); | 2303 ASSERT(member.type == NULL); |
| 2306 member.type = &Type::ZoneHandle(Type::VoidType()); | 2304 member.type = &Type::ZoneHandle(Type::VoidType()); |
| 2307 } else if (CurrentToken() == Token::kIDENT) { | 2305 } else if (CurrentToken() == Token::kIDENT) { |
| 2308 // This is either a type name or the name of a method/constructor/field. | 2306 // This is either a type name or the name of a method/constructor/field. |
| 2309 if (member.type == NULL) { | 2307 if ((member.type == NULL) && !member.has_factory) { |
| 2310 // We have not seen a member type yet, so we check if the next | 2308 // We have not seen a member type yet, so we check if the next |
| 2311 // identifier could represent a type before parsing it. | 2309 // identifier could represent a type before parsing it. |
| 2312 Token::Kind follower = LookaheadToken(1); | 2310 Token::Kind follower = LookaheadToken(1); |
| 2313 // We have an identifier followed by a 'follower' token. | 2311 // We have an identifier followed by a 'follower' token. |
| 2314 // We either parse a type or assume that no type is specified. | 2312 // We either parse a type or assume that no type is specified. |
| 2315 if ((follower == Token::kLT) || // Parameterized type. | 2313 if ((follower == Token::kLT) || // Parameterized type. |
| 2316 (follower == Token::kGET) || // Getter following a type. | 2314 (follower == Token::kGET) || // Getter following a type. |
| 2317 (follower == Token::kSET) || // Setter following a type. | 2315 (follower == Token::kSET) || // Setter following a type. |
| 2318 (follower == Token::kOPERATOR) || // Operator following a type. | 2316 (follower == Token::kOPERATOR) || // Operator following a type. |
| 2319 (follower == Token::kIDENT) || // Member name following a type. | 2317 (follower == Token::kIDENT) || // Member name following a type. |
| 2320 ((follower == Token::kPERIOD) && // Qualified class name of type, | 2318 ((follower == Token::kPERIOD) && // Qualified class name of type, |
| 2321 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. | 2319 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. |
| 2322 ASSERT(is_top_level_); | 2320 ASSERT(is_top_level_); |
| 2323 member.type = &Type::ZoneHandle(ParseType(kCanResolve)); | 2321 member.type = &Type::ZoneHandle(ParseType(kCanResolve)); |
| 2324 } | 2322 } |
| 2325 } | 2323 } |
| 2326 } | 2324 } |
| 2327 // Optionally parse a (possibly named) constructor name or factory. | 2325 // Optionally parse a (possibly named) constructor name or factory. |
| 2328 if ((CurrentToken() == Token::kIDENT) && | 2326 if ((CurrentToken() == Token::kIDENT) && |
| 2329 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 2327 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 2330 member.name = CurrentLiteral(); | 2328 member.name = CurrentLiteral(); |
| 2331 member.name_pos = this->token_index_; | 2329 member.name_pos = this->token_index_; |
| 2332 // Factory result type is the same as the type name of the factory. | 2330 ConsumeToken(); |
| 2333 // TODO(srdjan): Implement checks in class finalization when all types have | 2331 // Resolution of the factory result type is always postponed until class |
| 2334 // been resolved. | 2332 // finalization, so that the list of type parameters in the factory |
| 2335 if (member.has_factory && !member.name->Equals(members->class_name())) { | 2333 // signature can be checked at the same time. |
| 2336 const UnresolvedClass& type = | 2334 if (member.has_factory) { |
| 2335 const UnresolvedClass& unresolved_factory_class = |
| 2337 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, | 2336 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, |
| 2338 String::Handle(), | 2337 String::Handle(), |
| 2339 *(member.name))); | 2338 *(member.name))); |
| 2339 const Class& signature_class = Class::Handle( |
| 2340 Class::New(String::Handle(String::NewSymbol(":factory_signature")), |
| 2341 Script::Handle())); |
| 2342 signature_class.set_is_finalized(); |
| 2343 unresolved_factory_class.set_factory_signature_class(signature_class); |
| 2344 // The type arguments of the result type are set during finalization. |
| 2340 const TypeArguments& args = TypeArguments::Handle(); | 2345 const TypeArguments& args = TypeArguments::Handle(); |
| 2341 member.type = &Type::ZoneHandle(Type::NewParameterizedType(type, args)); | 2346 member.type = &Type::ZoneHandle( |
| 2347 Type::NewParameterizedType(unresolved_factory_class, args)); |
| 2348 ParseTypeParameters(signature_class); |
| 2342 } | 2349 } |
| 2343 ConsumeToken(); | |
| 2344 // We must be dealing with a constructor or named constructor. | 2350 // We must be dealing with a constructor or named constructor. |
| 2345 member.kind = RawFunction::kConstructor; | 2351 member.kind = RawFunction::kConstructor; |
| 2346 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); | 2352 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); |
| 2347 if (CurrentToken() == Token::kPERIOD) { | 2353 if (CurrentToken() == Token::kPERIOD) { |
| 2348 // Named constructor. | 2354 // Named constructor. |
| 2349 ConsumeToken(); | 2355 ConsumeToken(); |
| 2350 const String* name = ExpectIdentifier("identifier expected"); | 2356 const String* name = ExpectIdentifier("identifier expected"); |
| 2351 ctor_suffix = String::Concat(ctor_suffix, *name); | 2357 ctor_suffix = String::Concat(ctor_suffix, *name); |
| 2352 } | 2358 } |
| 2353 *member.name = String::Concat(*member.name, ctor_suffix); | 2359 *member.name = String::Concat(*member.name, ctor_suffix); |
| 2354 // Ensure that names are symbols. | 2360 // Ensure that names are symbols. |
| 2355 *member.name = String::NewSymbol(*member.name); | 2361 *member.name = String::NewSymbol(*member.name); |
| 2356 if (member.type == NULL) { | 2362 if (member.type == NULL) { |
| 2357 // TODO(regis): What are the type arguments? | 2363 ASSERT(!member.has_factory); |
| 2358 member.type = | 2364 // The body of the constructor cannot modify the type arguments of the |
| 2359 &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz()))); | 2365 // constructed instance, which is passed in as a hidden parameter. |
| 2366 // Therefore, there is no need to set the result type to be checked. |
| 2367 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2360 } else { | 2368 } else { |
| 2361 // The type can only be already set in the factory case. | 2369 // The type can only be already set in the factory case. |
| 2362 if (!member.has_factory) { | 2370 if (!member.has_factory) { |
| 2363 ErrorMsg(member.name_pos, "constructor must not specify return type"); | 2371 ErrorMsg(member.name_pos, "constructor must not specify return type"); |
| 2364 } | 2372 } |
| 2365 } | 2373 } |
| 2366 if (CurrentToken() != Token::kLPAREN) { | 2374 if (CurrentToken() != Token::kLPAREN) { |
| 2367 ErrorMsg("left parenthesis expected"); | 2375 ErrorMsg("left parenthesis expected"); |
| 2368 } | 2376 } |
| 2369 } else if (CurrentToken() == Token::kGET) { | 2377 } else if (CurrentToken() == Token::kGET) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2435 } else { | 2443 } else { |
| 2436 UnexpectedToken(); | 2444 UnexpectedToken(); |
| 2437 } | 2445 } |
| 2438 current_member_ = NULL; | 2446 current_member_ = NULL; |
| 2439 members->AddMember(member); | 2447 members->AddMember(member); |
| 2440 } | 2448 } |
| 2441 | 2449 |
| 2442 | 2450 |
| 2443 void Parser::ParseClassDefinition(GrowableArray<const Class*>* classes) { | 2451 void Parser::ParseClassDefinition(GrowableArray<const Class*>* classes) { |
| 2444 TRACE_PARSER("ParseClassDefinition"); | 2452 TRACE_PARSER("ParseClassDefinition"); |
| 2445 intptr_t class_pos = token_index_; | 2453 const intptr_t class_pos = token_index_; |
| 2446 ExpectToken(Token::kCLASS); | 2454 ExpectToken(Token::kCLASS); |
| 2447 intptr_t classname_pos = token_index_; | 2455 const intptr_t classname_pos = token_index_; |
| 2448 String& class_name = *ExpectIdentifier("class name expected"); | 2456 String& class_name = *ExpectIdentifier("class name expected"); |
| 2449 if (FLAG_trace_parser) { | 2457 if (FLAG_trace_parser) { |
| 2450 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 2458 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 2451 } | 2459 } |
| 2452 Class& cls = Class::ZoneHandle(); | 2460 Class& cls = Class::ZoneHandle(); |
| 2453 Object& obj = Object::Handle(library_.LookupObject(class_name)); | 2461 Object& obj = Object::Handle(library_.LookupObject(class_name)); |
| 2454 if (obj.IsNull()) { | 2462 if (obj.IsNull()) { |
| 2455 cls = Class::New(class_name, script_); | 2463 cls = Class::New(class_name, script_); |
| 2456 library_.AddClass(cls); | 2464 library_.AddClass(cls); |
| 2457 } else { | 2465 } else { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2530 /* is_const = */ false, | 2538 /* is_const = */ false, |
| 2531 class_desc->token_pos())); | 2539 class_desc->token_pos())); |
| 2532 ParamList params; | 2540 ParamList params; |
| 2533 // Add implicit 'this' parameter. | 2541 // Add implicit 'this' parameter. |
| 2534 params.AddReceiver(token_index_); | 2542 params.AddReceiver(token_index_); |
| 2535 // Add implicit parameter for construction phase. | 2543 // Add implicit parameter for construction phase. |
| 2536 params.AddFinalParameter(token_index_, kPhaseParameterName, | 2544 params.AddFinalParameter(token_index_, kPhaseParameterName, |
| 2537 &Type::ZoneHandle(Type::DynamicType())); | 2545 &Type::ZoneHandle(Type::DynamicType())); |
| 2538 | 2546 |
| 2539 AddFormalParamsToFunction(¶ms, ctor); | 2547 AddFormalParamsToFunction(¶ms, ctor); |
| 2540 // TODO(regis): What are the type arguments? | 2548 // The body of the constructor cannot modify the type arguments of the |
| 2541 Type& result_type = Type::ZoneHandle( | 2549 // constructed instance, which is passed in as a hidden parameter. |
| 2542 Type::NewRawType(Class::Handle(class_desc->clazz()))); | 2550 // Therefore, there is no need to set the result type to be checked. |
| 2551 const Type& result_type = Type::ZoneHandle(Type::DynamicType()); |
| 2543 ctor.set_result_type(result_type); | 2552 ctor.set_result_type(result_type); |
| 2544 class_desc->AddFunction(&ctor); | 2553 class_desc->AddFunction(&ctor); |
| 2545 } | 2554 } |
| 2546 | 2555 |
| 2547 // Check for cycles in constructor redirection. | 2556 // Check for cycles in constructor redirection. |
| 2548 const GrowableArray<MemberDesc>& members = class_desc->members(); | 2557 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 2549 for (int i = 0; i < members.length(); i++) { | 2558 for (int i = 0; i < members.length(); i++) { |
| 2550 MemberDesc* member = &members[i]; | 2559 MemberDesc* member = &members[i]; |
| 2551 GrowableArray<MemberDesc*> ctors; | 2560 GrowableArray<MemberDesc*> ctors; |
| 2552 while ((member != NULL) && (member->redirect_name != NULL)) { | 2561 while ((member != NULL) && (member->redirect_name != NULL)) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2591 SetPosition(saved_pos); | 2600 SetPosition(saved_pos); |
| 2592 return is_alias_name; | 2601 return is_alias_name; |
| 2593 } | 2602 } |
| 2594 | 2603 |
| 2595 | 2604 |
| 2596 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { | 2605 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { |
| 2597 TRACE_PARSER("ParseFunctionTypeAlias"); | 2606 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 2598 ExpectToken(Token::kTYPEDEF); | 2607 ExpectToken(Token::kTYPEDEF); |
| 2599 | 2608 |
| 2600 Type& result_type = Type::Handle(Type::DynamicType()); | 2609 Type& result_type = Type::Handle(Type::DynamicType()); |
| 2601 intptr_t result_type_pos = token_index_; | 2610 const intptr_t result_type_pos = token_index_; |
| 2602 if (CurrentToken() == Token::kVOID) { | 2611 if (CurrentToken() == Token::kVOID) { |
| 2603 ConsumeToken(); | 2612 ConsumeToken(); |
| 2604 result_type = Type::VoidType(); | 2613 result_type = Type::VoidType(); |
| 2605 } else if (!IsFunctionTypeAliasName()) { | 2614 } else if (!IsFunctionTypeAliasName()) { |
| 2606 result_type = ParseType(kDoNotResolve); // No owner class yet. | 2615 result_type = ParseType(kDoNotResolve); // No owner class yet. |
| 2607 } | 2616 } |
| 2608 | 2617 |
| 2609 if (CurrentToken() != Token::kIDENT) { | 2618 if (CurrentToken() != Token::kIDENT) { |
| 2610 ErrorMsg("function alias name expected"); | 2619 ErrorMsg("function alias name expected"); |
| 2611 } | 2620 } |
| 2612 const intptr_t alias_name_pos = token_index_; | 2621 const intptr_t alias_name_pos = token_index_; |
| 2613 const String* alias_name = CurrentLiteral(); | 2622 const String* alias_name = CurrentLiteral(); |
| 2614 ConsumeToken(); | 2623 ConsumeToken(); |
| 2615 | 2624 |
| 2616 // Allocate an interface to hold the type parameters and their 'extends' | 2625 // Allocate an interface to hold the type parameters and their 'extends' |
| 2617 // constraints. Make it the owner of the function type descriptor. | 2626 // constraints. Make it the owner of the function type descriptor. |
| 2618 const Class& alias_owner = Class::Handle( | 2627 const Class& alias_owner = Class::Handle( |
| 2619 Class::New(String::Handle(String::NewSymbol(":alias_owner")), | 2628 Class::New(String::Handle(String::NewSymbol(":alias_owner")), |
| 2620 Script::Handle())); | 2629 Script::Handle())); |
| 2621 alias_owner.set_is_interface(); | 2630 alias_owner.set_is_interface(); |
| 2622 set_current_class(alias_owner); | 2631 set_current_class(alias_owner); |
| 2623 ParseTypeParameters(alias_owner); | 2632 ParseTypeParameters(alias_owner); |
| 2624 if (CurrentToken() != Token::kLPAREN) { | 2633 if (CurrentToken() != Token::kLPAREN) { |
| 2625 ErrorMsg("formal parameter list expected"); | 2634 ErrorMsg("formal parameter list expected"); |
| 2626 } | 2635 } |
| 2627 | 2636 |
| 2628 // At this point, the type parameters have been parsed, so we can resolve the | 2637 // At this point, the type parameters have been parsed, so we can resolve the |
| 2629 // result type. | 2638 // result type. |
| 2630 if (!result_type.IsNull() && !result_type.IsResolved()) { | 2639 if (!result_type.IsNull()) { |
| 2631 ResolveTypeFromClass(result_type_pos, alias_owner, &result_type); | 2640 TryResolveTypeFromClass(result_type_pos, alias_owner, &result_type); |
| 2632 } | 2641 } |
| 2633 ParamList func_params; | 2642 ParamList func_params; |
| 2634 const bool no_explicit_default_values = false; | 2643 const bool no_explicit_default_values = false; |
| 2635 ParseFormalParameterList(no_explicit_default_values, &func_params); | 2644 ParseFormalParameterList(no_explicit_default_values, &func_params); |
| 2636 // The field 'is_static' has no meaning for signature functions. | 2645 // The field 'is_static' has no meaning for signature functions. |
| 2637 Function& signature_function = Function::Handle( | 2646 Function& signature_function = Function::Handle( |
| 2638 Function::New(*alias_name, | 2647 Function::New(*alias_name, |
| 2639 RawFunction::kSignatureFunction, | 2648 RawFunction::kSignatureFunction, |
| 2640 /* is_static = */ false, | 2649 /* is_static = */ false, |
| 2641 /* is_const = */ false, | 2650 /* is_const = */ false, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2678 "'%s' is already defined" : "'%s' is already defined as class"; | 2687 "'%s' is already defined" : "'%s' is already defined as class"; |
| 2679 ErrorMsg(alias_name_pos, format, alias_name->ToCString()); | 2688 ErrorMsg(alias_name_pos, format, alias_name->ToCString()); |
| 2680 } | 2689 } |
| 2681 ExpectSemicolon(); | 2690 ExpectSemicolon(); |
| 2682 classes->Add(&function_type_alias); | 2691 classes->Add(&function_type_alias); |
| 2683 } | 2692 } |
| 2684 | 2693 |
| 2685 | 2694 |
| 2686 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { | 2695 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { |
| 2687 TRACE_PARSER("ParseInterfaceDefinition"); | 2696 TRACE_PARSER("ParseInterfaceDefinition"); |
| 2688 intptr_t interface_pos = token_index_; | 2697 const intptr_t interface_pos = token_index_; |
| 2689 ExpectToken(Token::kINTERFACE); | 2698 ExpectToken(Token::kINTERFACE); |
| 2690 intptr_t interfacename_pos = token_index_; | 2699 const intptr_t interfacename_pos = token_index_; |
| 2691 String& interface_name = *ExpectIdentifier("interface name expected"); | 2700 String& interface_name = *ExpectIdentifier("interface name expected"); |
| 2692 if (FLAG_trace_parser) { | 2701 if (FLAG_trace_parser) { |
| 2693 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | 2702 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); |
| 2694 } | 2703 } |
| 2695 Class& interface = Class::ZoneHandle(); | 2704 Class& interface = Class::ZoneHandle(); |
| 2696 Object& obj = Object::Handle(library_.LookupObject(interface_name)); | 2705 Object& obj = Object::Handle(library_.LookupObject(interface_name)); |
| 2697 if (obj.IsNull()) { | 2706 if (obj.IsNull()) { |
| 2698 interface = Class::NewInterface(interface_name, script_); | 2707 interface = Class::NewInterface(interface_name, script_); |
| 2699 library_.AddClass(interface); | 2708 library_.AddClass(interface); |
| 2700 } else { | 2709 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2720 | 2729 |
| 2721 if (CurrentToken() == Token::kEXTENDS) { | 2730 if (CurrentToken() == Token::kEXTENDS) { |
| 2722 Array& interfaces = Array::Handle(); | 2731 Array& interfaces = Array::Handle(); |
| 2723 const intptr_t interfaces_pos = token_index_; | 2732 const intptr_t interfaces_pos = token_index_; |
| 2724 interfaces = ParseInterfaceList(); | 2733 interfaces = ParseInterfaceList(); |
| 2725 AddInterfaces(interfaces_pos, interface, interfaces); | 2734 AddInterfaces(interfaces_pos, interface, interfaces); |
| 2726 } | 2735 } |
| 2727 | 2736 |
| 2728 if (CurrentToken() == Token::kFACTORY) { | 2737 if (CurrentToken() == Token::kFACTORY) { |
| 2729 ConsumeToken(); | 2738 ConsumeToken(); |
| 2730 Type& factory_type = Type::Handle(); | 2739 const intptr_t factory_pos = token_index_; |
| 2731 const intptr_t factory_type_pos = token_index_; | 2740 QualIdent factory_name; |
| 2732 factory_type = ParseType(kCanResolve); | 2741 ParseQualIdent(&factory_name); |
| 2733 if (factory_type.IsInterfaceType()) { | 2742 if (factory_name.is_local_scope_ident) { |
| 2734 ErrorMsg(factory_type_pos, | 2743 ErrorMsg(factory_pos, |
| 2735 "interface '%s' must have a factory class " | 2744 "using '%s' in this context is invalid", |
| 2736 "but '%s' is an interface", | 2745 factory_name.ident->ToCString()); |
| 2737 interface_name.ToCString(), | |
| 2738 String::Handle(factory_type.Name()).ToCString()); | |
| 2739 } | 2746 } |
| 2740 interface.set_factory_type(factory_type); | 2747 String& qualifier = String::Handle(); |
| 2748 if (factory_name.qualifier != NULL) { |
| 2749 qualifier ^= factory_name.qualifier->raw(); |
| 2750 } |
| 2751 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( |
| 2752 UnresolvedClass::New(factory_pos, qualifier, *(factory_name.ident))); |
| 2753 const Class& signature_class = Class::Handle( |
| 2754 Class::New(String::Handle(String::NewSymbol(":factory_signature")), |
| 2755 Script::Handle())); |
| 2756 signature_class.set_is_finalized(); |
| 2757 ParseTypeParameters(signature_class); |
| 2758 unresolved_factory_class.set_factory_signature_class(signature_class); |
| 2759 interface.set_factory_class(unresolved_factory_class); |
| 2741 } | 2760 } |
| 2742 | 2761 |
| 2743 ExpectToken(Token::kLBRACE); | 2762 ExpectToken(Token::kLBRACE); |
| 2744 ClassDesc members(interface, interface_name, true, interface_pos); | 2763 ClassDesc members(interface, interface_name, true, interface_pos); |
| 2745 while (CurrentToken() != Token::kRBRACE) { | 2764 while (CurrentToken() != Token::kRBRACE) { |
| 2746 ParseClassMemberDefinition(&members); | 2765 ParseClassMemberDefinition(&members); |
| 2747 } | 2766 } |
| 2748 ExpectToken(Token::kRBRACE); | 2767 ExpectToken(Token::kRBRACE); |
| 2749 | 2768 |
| 2750 interface.SetFields(Array::Handle(NewArray<Field>(members.fields()))); | 2769 interface.SetFields(Array::Handle(NewArray<Field>(members.fields()))); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2803 ConsumeToken(); | 2822 ConsumeToken(); |
| 2804 ExpectIdentifier("name expected"); | 2823 ExpectIdentifier("name expected"); |
| 2805 } | 2824 } |
| 2806 SkipTypeArguments(); | 2825 SkipTypeArguments(); |
| 2807 } | 2826 } |
| 2808 } | 2827 } |
| 2809 | 2828 |
| 2810 | 2829 |
| 2811 void Parser::ParseTypeParameters(const Class& cls) { | 2830 void Parser::ParseTypeParameters(const Class& cls) { |
| 2812 if (CurrentToken() == Token::kLT) { | 2831 if (CurrentToken() == Token::kLT) { |
| 2832 const intptr_t type_pos = token_index_; |
| 2813 GrowableArray<String*> type_parameters; | 2833 GrowableArray<String*> type_parameters; |
| 2814 GrowableArray<Type*> type_parameter_extends; | 2834 GrowableArray<Type*> type_parameter_extends; |
| 2815 do { | 2835 do { |
| 2816 ConsumeToken(); | 2836 ConsumeToken(); |
| 2817 if (CurrentToken() != Token::kIDENT) { | 2837 if (CurrentToken() != Token::kIDENT) { |
| 2818 ErrorMsg("type parameter name expected"); | 2838 ErrorMsg("type parameter name expected"); |
| 2819 } | 2839 } |
| 2820 String& type_parameter_name = *CurrentLiteral(); | 2840 String& type_parameter_name = *CurrentLiteral(); |
| 2821 ConsumeToken(); | 2841 ConsumeToken(); |
| 2822 Type& type_extends = Type::ZoneHandle(Type::DynamicType()); | 2842 Type& type_extends = Type::ZoneHandle(Type::DynamicType()); |
| 2823 if (CurrentToken() == Token::kEXTENDS) { | 2843 if (CurrentToken() == Token::kEXTENDS) { |
| 2824 ConsumeToken(); | 2844 ConsumeToken(); |
| 2825 type_extends = ParseType(kCanResolve); | 2845 type_extends = ParseType(kCanResolve); |
| 2826 } | 2846 } |
| 2827 type_parameters.Add(&type_parameter_name); | 2847 type_parameters.Add(&type_parameter_name); |
| 2828 type_parameter_extends.Add(&type_extends); | 2848 type_parameter_extends.Add(&type_extends); |
| 2829 } while (CurrentToken() == Token::kCOMMA); | 2849 } while (CurrentToken() == Token::kCOMMA); |
| 2830 Token::Kind token = CurrentToken(); | 2850 Token::Kind token = CurrentToken(); |
| 2831 if ((token == Token::kGT) || | 2851 if ((token == Token::kGT) || |
| 2832 (token == Token::kSAR) || | 2852 (token == Token::kSAR) || |
| 2833 (token == Token::kSHR)) { | 2853 (token == Token::kSHR)) { |
| 2834 ConsumeRightAngleBracket(); | 2854 ConsumeRightAngleBracket(); |
| 2835 } else { | 2855 } else { |
| 2836 ErrorMsg("right angle bracket expected"); | 2856 ErrorMsg("right angle bracket expected"); |
| 2837 } | 2857 } |
| 2838 cls.set_type_parameters(Array::Handle(NewArray<String>(type_parameters))); | 2858 cls.set_type_parameters(Array::Handle(NewArray<String>(type_parameters))); |
| 2839 cls.set_type_parameter_extends( | 2859 const TypeArray& extends_array = |
| 2840 TypeArray::Handle(NewTypeArray(type_parameter_extends))); | 2860 TypeArray::Handle(NewTypeArray(type_parameter_extends)); |
| 2861 cls.set_type_parameter_extends(extends_array); |
| 2862 // Try to resolve the upper bounds, which will at least resolve the |
| 2863 // referenced type parameters. |
| 2864 Type& type_extends = Type::Handle(); |
| 2865 const intptr_t num_types = extends_array.Length(); |
| 2866 for (intptr_t i = 0; i < num_types; i++) { |
| 2867 type_extends = extends_array.TypeAt(i); |
| 2868 TryResolveTypeFromClass(type_pos, cls, &type_extends); |
| 2869 extends_array.SetTypeAt(i, type_extends); |
| 2870 } |
| 2841 } | 2871 } |
| 2842 } | 2872 } |
| 2843 | 2873 |
| 2844 | 2874 |
| 2845 RawTypeArguments* Parser::ParseTypeArguments(TypeResolution type_resolution) { | 2875 RawTypeArguments* Parser::ParseTypeArguments(TypeResolution type_resolution) { |
| 2846 if (CurrentToken() == Token::kLT) { | 2876 if (CurrentToken() == Token::kLT) { |
| 2847 GrowableArray<Type*> types; | 2877 GrowableArray<Type*> types; |
| 2848 do { | 2878 do { |
| 2849 ConsumeToken(); | 2879 ConsumeToken(); |
| 2850 Type& type = Type::ZoneHandle(ParseType(type_resolution)); | 2880 Type& type = Type::ZoneHandle(ParseType(type_resolution)); |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3019 } else { | 3049 } else { |
| 3020 result_type = ParseType(kCanResolve); | 3050 result_type = ParseType(kCanResolve); |
| 3021 } | 3051 } |
| 3022 is_getter = (CurrentToken() == Token::kGET); | 3052 is_getter = (CurrentToken() == Token::kGET); |
| 3023 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 3053 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
| 3024 ConsumeToken(); | 3054 ConsumeToken(); |
| 3025 } else { | 3055 } else { |
| 3026 UnexpectedToken(); | 3056 UnexpectedToken(); |
| 3027 } | 3057 } |
| 3028 } | 3058 } |
| 3029 intptr_t name_pos = token_index_; | 3059 const intptr_t name_pos = token_index_; |
| 3030 const String* field_name = ExpectIdentifier("accessor name expected"); | 3060 const String* field_name = ExpectIdentifier("accessor name expected"); |
| 3031 | 3061 |
| 3032 if (CurrentToken() != Token::kLPAREN) { | 3062 if (CurrentToken() != Token::kLPAREN) { |
| 3033 ErrorMsg("'(' expected"); | 3063 ErrorMsg("'(' expected"); |
| 3034 } | 3064 } |
| 3035 intptr_t accessor_pos = token_index_; | 3065 const intptr_t accessor_pos = token_index_; |
| 3036 ParamList params; | 3066 ParamList params; |
| 3037 const bool allow_explicit_default_values = true; | 3067 const bool allow_explicit_default_values = true; |
| 3038 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 3068 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 3039 String& accessor_name = String::ZoneHandle(); | 3069 String& accessor_name = String::ZoneHandle(); |
| 3040 int expected_num_parameters = -1; | 3070 int expected_num_parameters = -1; |
| 3041 if (is_getter) { | 3071 if (is_getter) { |
| 3042 expected_num_parameters = 0; | 3072 expected_num_parameters = 0; |
| 3043 accessor_name = Field::GetterName(*field_name); | 3073 accessor_name = Field::GetterName(*field_name); |
| 3044 } else { | 3074 } else { |
| 3045 expected_num_parameters = 1; | 3075 expected_num_parameters = 1; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3107 Api::NewLocalHandle(url)); | 3137 Api::NewLocalHandle(url)); |
| 3108 if (Dart_IsError(result)) { | 3138 if (Dart_IsError(result)) { |
| 3109 ErrorMsg(token_pos, "library handler failed: %s", Dart_GetError(result)); | 3139 ErrorMsg(token_pos, "library handler failed: %s", Dart_GetError(result)); |
| 3110 } | 3140 } |
| 3111 return result; | 3141 return result; |
| 3112 } | 3142 } |
| 3113 | 3143 |
| 3114 | 3144 |
| 3115 void Parser::ParseLibraryImport() { | 3145 void Parser::ParseLibraryImport() { |
| 3116 while (CurrentToken() == Token::kIMPORT) { | 3146 while (CurrentToken() == Token::kIMPORT) { |
| 3117 intptr_t import_pos = token_index_; | 3147 const intptr_t import_pos = token_index_; |
| 3118 ConsumeToken(); | 3148 ConsumeToken(); |
| 3119 ExpectToken(Token::kLPAREN); | 3149 ExpectToken(Token::kLPAREN); |
| 3120 if (CurrentToken() != Token::kSTRING) { | 3150 if (CurrentToken() != Token::kSTRING) { |
| 3121 ErrorMsg("library url expected"); | 3151 ErrorMsg("library url expected"); |
| 3122 } | 3152 } |
| 3123 const String& url = *CurrentLiteral(); | 3153 const String& url = *CurrentLiteral(); |
| 3124 ConsumeToken(); | 3154 ConsumeToken(); |
| 3125 String& prefix = String::Handle(); | 3155 String& prefix = String::Handle(); |
| 3126 if (CurrentToken() == Token::kCOMMA) { | 3156 if (CurrentToken() == Token::kCOMMA) { |
| 3127 ConsumeToken(); | 3157 ConsumeToken(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3164 const LibraryPrefix& library_prefix = | 3194 const LibraryPrefix& library_prefix = |
| 3165 LibraryPrefix::Handle(LibraryPrefix::New(prefix, library)); | 3195 LibraryPrefix::Handle(LibraryPrefix::New(prefix, library)); |
| 3166 library_.AddObject(library_prefix, prefix); | 3196 library_.AddObject(library_prefix, prefix); |
| 3167 } | 3197 } |
| 3168 } | 3198 } |
| 3169 } | 3199 } |
| 3170 | 3200 |
| 3171 | 3201 |
| 3172 void Parser::ParseLibraryInclude() { | 3202 void Parser::ParseLibraryInclude() { |
| 3173 while (CurrentToken() == Token::kSOURCE) { | 3203 while (CurrentToken() == Token::kSOURCE) { |
| 3174 intptr_t source_pos = token_index_; | 3204 const intptr_t source_pos = token_index_; |
| 3175 ConsumeToken(); | 3205 ConsumeToken(); |
| 3176 ExpectToken(Token::kLPAREN); | 3206 ExpectToken(Token::kLPAREN); |
| 3177 if (CurrentToken() != Token::kSTRING) { | 3207 if (CurrentToken() != Token::kSTRING) { |
| 3178 ErrorMsg("source url expected"); | 3208 ErrorMsg("source url expected"); |
| 3179 } | 3209 } |
| 3180 const String& url = *CurrentLiteral(); | 3210 const String& url = *CurrentLiteral(); |
| 3181 ConsumeToken(); | 3211 ConsumeToken(); |
| 3182 ExpectToken(Token::kRPAREN); | 3212 ExpectToken(Token::kRPAREN); |
| 3183 ExpectToken(Token::kSEMICOLON); | 3213 ExpectToken(Token::kSEMICOLON); |
| 3184 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, | 3214 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3378 } | 3408 } |
| 3379 | 3409 |
| 3380 | 3410 |
| 3381 // Builds ReturnNode/NativeBodyNode for a native function. | 3411 // Builds ReturnNode/NativeBodyNode for a native function. |
| 3382 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 3412 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 3383 const Function& func) { | 3413 const Function& func) { |
| 3384 const Class& cls = Class::Handle(func.owner()); | 3414 const Class& cls = Class::Handle(func.owner()); |
| 3385 const int num_parameters = params->parameters->length(); | 3415 const int num_parameters = params->parameters->length(); |
| 3386 | 3416 |
| 3387 // Parse the function name out. | 3417 // Parse the function name out. |
| 3388 intptr_t native_pos = token_index_; | 3418 const intptr_t native_pos = token_index_; |
| 3389 const String& native_name = ParseNativeDeclaration(); | 3419 const String& native_name = ParseNativeDeclaration(); |
| 3390 | 3420 |
| 3391 // Now resolve the native function to the corresponding native entrypoint. | 3421 // Now resolve the native function to the corresponding native entrypoint. |
| 3392 NativeFunction native_function = NativeEntry::ResolveNative(cls, | 3422 NativeFunction native_function = NativeEntry::ResolveNative(cls, |
| 3393 native_name, | 3423 native_name, |
| 3394 num_parameters); | 3424 num_parameters); |
| 3395 if (native_function == NULL) { | 3425 if (native_function == NULL) { |
| 3396 ErrorMsg(native_pos, "native function '%s' cannot be found", | 3426 ErrorMsg(native_pos, "native function '%s' cannot be found", |
| 3397 native_name.ToCString()); | 3427 native_name.ToCString()); |
| 3398 } | 3428 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3572 const String* function_name = NULL; | 3602 const String* function_name = NULL; |
| 3573 | 3603 |
| 3574 result_type = Type::DynamicType(); | 3604 result_type = Type::DynamicType(); |
| 3575 if (CurrentToken() == Token::kVOID) { | 3605 if (CurrentToken() == Token::kVOID) { |
| 3576 ConsumeToken(); | 3606 ConsumeToken(); |
| 3577 result_type = Type::VoidType(); | 3607 result_type = Type::VoidType(); |
| 3578 } else if ((CurrentToken() == Token::kIDENT) && | 3608 } else if ((CurrentToken() == Token::kIDENT) && |
| 3579 (LookaheadToken(1) != Token::kLPAREN)) { | 3609 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3580 result_type = ParseType(kMustResolve); | 3610 result_type = ParseType(kMustResolve); |
| 3581 } | 3611 } |
| 3582 intptr_t ident_pos = token_index_; | 3612 const intptr_t ident_pos = token_index_; |
| 3583 if (CurrentToken() == Token::kIDENT) { | 3613 if (CurrentToken() == Token::kIDENT) { |
| 3584 variable_name = CurrentLiteral(); | 3614 variable_name = CurrentLiteral(); |
| 3585 function_name = variable_name; | 3615 function_name = variable_name; |
| 3586 ConsumeToken(); | 3616 ConsumeToken(); |
| 3587 } else { | 3617 } else { |
| 3588 if (!is_literal) { | 3618 if (!is_literal) { |
| 3589 ErrorMsg("function name expected"); | 3619 ErrorMsg("function name expected"); |
| 3590 } | 3620 } |
| 3591 const String& anonymous_function_name = | 3621 const String& anonymous_function_name = |
| 3592 String::ZoneHandle(String::NewSymbol("function")); | 3622 String::ZoneHandle(String::NewSymbol("function")); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3772 | 3802 |
| 3773 | 3803 |
| 3774 // Returns true if the next tokens can be parsed as a type with optional | 3804 // Returns true if the next tokens can be parsed as a type with optional |
| 3775 // type parameters. Current token position is not restored. | 3805 // type parameters. Current token position is not restored. |
| 3776 bool Parser::IsOptionalType() { | 3806 bool Parser::IsOptionalType() { |
| 3777 if (CurrentToken() == Token::kIDENT) { | 3807 if (CurrentToken() == Token::kIDENT) { |
| 3778 QualIdent type_name; | 3808 QualIdent type_name; |
| 3779 ParseQualIdent(&type_name); | 3809 ParseQualIdent(&type_name); |
| 3780 // Check if the type_name has been defined as a variable in a local scope, | 3810 // Check if the type_name has been defined as a variable in a local scope, |
| 3781 // hiding the type. | 3811 // hiding the type. |
| 3782 if (type_name.local_scope_ident) { | 3812 if (type_name.is_local_scope_ident) { |
| 3783 return false; | 3813 return false; |
| 3784 } | 3814 } |
| 3785 if (CurrentToken() == Token::kLT && !IsTypeParameter()) { | 3815 if (CurrentToken() == Token::kLT && !IsTypeParameter()) { |
| 3786 return false; | 3816 return false; |
| 3787 } | 3817 } |
| 3788 } | 3818 } |
| 3789 return true; | 3819 return true; |
| 3790 } | 3820 } |
| 3791 | 3821 |
| 3792 | 3822 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3809 // ('var' | 'final' | type ident (';' | '=' | ',')) | 3839 // ('var' | 'final' | type ident (';' | '=' | ',')) |
| 3810 // Token position remains unchanged. | 3840 // Token position remains unchanged. |
| 3811 bool Parser::IsVariableDeclaration() { | 3841 bool Parser::IsVariableDeclaration() { |
| 3812 if ((CurrentToken() == Token::kVAR) || | 3842 if ((CurrentToken() == Token::kVAR) || |
| 3813 (CurrentToken() == Token::kFINAL)) { | 3843 (CurrentToken() == Token::kFINAL)) { |
| 3814 return true; | 3844 return true; |
| 3815 } | 3845 } |
| 3816 if (CurrentToken() != Token::kIDENT) { | 3846 if (CurrentToken() != Token::kIDENT) { |
| 3817 return false; | 3847 return false; |
| 3818 } | 3848 } |
| 3819 intptr_t saved_pos = token_index_; | 3849 const intptr_t saved_pos = token_index_; |
| 3820 bool is_var_decl = false; | 3850 bool is_var_decl = false; |
| 3821 if (IsOptionalType()) { | 3851 if (IsOptionalType()) { |
| 3822 if (CurrentToken() == Token::kIDENT) { | 3852 if (CurrentToken() == Token::kIDENT) { |
| 3823 ConsumeToken(); | 3853 ConsumeToken(); |
| 3824 if ((CurrentToken() == Token::kSEMICOLON) || | 3854 if ((CurrentToken() == Token::kSEMICOLON) || |
| 3825 (CurrentToken() == Token::kCOMMA) || | 3855 (CurrentToken() == Token::kCOMMA) || |
| 3826 (CurrentToken() == Token::kASSIGN)) { | 3856 (CurrentToken() == Token::kASSIGN)) { |
| 3827 is_var_decl = true; | 3857 is_var_decl = true; |
| 3828 } | 3858 } |
| 3829 } | 3859 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3846 return ((CurrentToken() == Token::kIDENT) && | 3876 return ((CurrentToken() == Token::kIDENT) && |
| 3847 (LookaheadToken(1) == Token::kLPAREN)) || | 3877 (LookaheadToken(1) == Token::kLPAREN)) || |
| 3848 IsFunctionDeclaration(); | 3878 IsFunctionDeclaration(); |
| 3849 } | 3879 } |
| 3850 | 3880 |
| 3851 | 3881 |
| 3852 bool Parser::IsTopLevelAccessor() { | 3882 bool Parser::IsTopLevelAccessor() { |
| 3853 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 3883 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 3854 return true; | 3884 return true; |
| 3855 } | 3885 } |
| 3856 intptr_t saved_pos = token_index_; | 3886 const intptr_t saved_pos = token_index_; |
| 3857 if (IsReturnType()) { | 3887 if (IsReturnType()) { |
| 3858 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 3888 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 3859 if (LookaheadToken(1) == Token::kIDENT) { // Accessor name. | 3889 if (LookaheadToken(1) == Token::kIDENT) { // Accessor name. |
| 3860 SetPosition(saved_pos); | 3890 SetPosition(saved_pos); |
| 3861 return true; | 3891 return true; |
| 3862 } | 3892 } |
| 3863 } | 3893 } |
| 3864 } | 3894 } |
| 3865 SetPosition(saved_pos); | 3895 SetPosition(saved_pos); |
| 3866 return false; | 3896 return false; |
| 3867 } | 3897 } |
| 3868 | 3898 |
| 3869 | 3899 |
| 3870 bool Parser::IsFunctionLiteral() { | 3900 bool Parser::IsFunctionLiteral() { |
| 3871 if (!allow_function_literals_) { | 3901 if (!allow_function_literals_) { |
| 3872 return false; | 3902 return false; |
| 3873 } | 3903 } |
| 3874 intptr_t saved_pos = token_index_; | 3904 const intptr_t saved_pos = token_index_; |
| 3875 bool is_function_literal = false; | 3905 bool is_function_literal = false; |
| 3876 if ((CurrentToken() == Token::kIDENT) && | 3906 if ((CurrentToken() == Token::kIDENT) && |
| 3877 (LookaheadToken(1) == Token::kLPAREN)) { | 3907 (LookaheadToken(1) == Token::kLPAREN)) { |
| 3878 ConsumeToken(); // Consume function identifier. | 3908 ConsumeToken(); // Consume function identifier. |
| 3879 } else if (IsReturnType()) { | 3909 } else if (IsReturnType()) { |
| 3880 if (CurrentToken() != Token::kIDENT) { | 3910 if (CurrentToken() != Token::kIDENT) { |
| 3881 SetPosition(saved_pos); | 3911 SetPosition(saved_pos); |
| 3882 return false; | 3912 return false; |
| 3883 } | 3913 } |
| 3884 ConsumeToken(); // Comsume function identifier. | 3914 ConsumeToken(); // Comsume function identifier. |
| 3885 } | 3915 } |
| 3886 if (CurrentToken() == Token::kLPAREN) { | 3916 if (CurrentToken() == Token::kLPAREN) { |
| 3887 SkipToMatchingParenthesis(); | 3917 SkipToMatchingParenthesis(); |
| 3888 if ((CurrentToken() == Token::kLBRACE) || | 3918 if ((CurrentToken() == Token::kLBRACE) || |
| 3889 (CurrentToken() == Token::kARROW)) { | 3919 (CurrentToken() == Token::kARROW)) { |
| 3890 is_function_literal = true; | 3920 is_function_literal = true; |
| 3891 } | 3921 } |
| 3892 } | 3922 } |
| 3893 SetPosition(saved_pos); | 3923 SetPosition(saved_pos); |
| 3894 return is_function_literal; | 3924 return is_function_literal; |
| 3895 } | 3925 } |
| 3896 | 3926 |
| 3897 | 3927 |
| 3898 // Current token position is the token after the opening ( of the for | 3928 // Current token position is the token after the opening ( of the for |
| 3899 // statement. Returns true if we recognize a for ( .. in expr) | 3929 // statement. Returns true if we recognize a for ( .. in expr) |
| 3900 // statement. | 3930 // statement. |
| 3901 bool Parser::IsForInStatement() { | 3931 bool Parser::IsForInStatement() { |
| 3902 intptr_t saved_pos = token_index_; | 3932 const intptr_t saved_pos = token_index_; |
| 3903 bool result = false; | 3933 bool result = false; |
| 3904 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { | 3934 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { |
| 3905 ConsumeToken(); | 3935 ConsumeToken(); |
| 3906 } | 3936 } |
| 3907 if (CurrentToken() == Token::kIDENT) { | 3937 if (CurrentToken() == Token::kIDENT) { |
| 3908 if (LookaheadToken(1) == Token::kIN) { | 3938 if (LookaheadToken(1) == Token::kIN) { |
| 3909 result = true; | 3939 result = true; |
| 3910 } else if (IsOptionalType()) { | 3940 } else if (IsOptionalType()) { |
| 3911 if (CurrentToken() == Token::kIDENT) { | 3941 if (CurrentToken() == Token::kIDENT) { |
| 3912 ConsumeToken(); | 3942 ConsumeToken(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3938 } | 3968 } |
| 3939 return false; | 3969 return false; |
| 3940 } | 3970 } |
| 3941 | 3971 |
| 3942 | 3972 |
| 3943 void Parser::ParseStatementSequence() { | 3973 void Parser::ParseStatementSequence() { |
| 3944 TRACE_PARSER("ParseStatementSequence"); | 3974 TRACE_PARSER("ParseStatementSequence"); |
| 3945 const bool dead_code_allowed = true; | 3975 const bool dead_code_allowed = true; |
| 3946 bool abrupt_completing_seen = false; | 3976 bool abrupt_completing_seen = false; |
| 3947 while (CurrentToken() != Token::kRBRACE) { | 3977 while (CurrentToken() != Token::kRBRACE) { |
| 3948 intptr_t statement_pos = token_index_; | 3978 const intptr_t statement_pos = token_index_; |
| 3949 AstNode* statement = ParseStatement(); | 3979 AstNode* statement = ParseStatement(); |
| 3950 if (statement != NULL) { | 3980 if (statement != NULL) { |
| 3951 if (!dead_code_allowed && abrupt_completing_seen) { | 3981 if (!dead_code_allowed && abrupt_completing_seen) { |
| 3952 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); | 3982 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); |
| 3953 } | 3983 } |
| 3954 current_block_->statements->Add(statement); | 3984 current_block_->statements->Add(statement); |
| 3955 abrupt_completing_seen |= IsAbruptCompleting(statement); | 3985 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 3956 } | 3986 } |
| 3957 } | 3987 } |
| 3958 } | 3988 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3983 } | 4013 } |
| 3984 } | 4014 } |
| 3985 SequenceNode* sequence = CloseBlock(); | 4015 SequenceNode* sequence = CloseBlock(); |
| 3986 return sequence; | 4016 return sequence; |
| 3987 } | 4017 } |
| 3988 | 4018 |
| 3989 | 4019 |
| 3990 AstNode* Parser::ParseIfStatement(String* label_name) { | 4020 AstNode* Parser::ParseIfStatement(String* label_name) { |
| 3991 TRACE_PARSER("ParseIfStatement"); | 4021 TRACE_PARSER("ParseIfStatement"); |
| 3992 ASSERT(CurrentToken() == Token::kIF); | 4022 ASSERT(CurrentToken() == Token::kIF); |
| 3993 intptr_t if_pos = token_index_; | 4023 const intptr_t if_pos = token_index_; |
| 3994 SourceLabel* label = NULL; | 4024 SourceLabel* label = NULL; |
| 3995 if (label_name != NULL) { | 4025 if (label_name != NULL) { |
| 3996 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 4026 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
| 3997 OpenBlock(); | 4027 OpenBlock(); |
| 3998 current_block_->scope->AddLabel(label); | 4028 current_block_->scope->AddLabel(label); |
| 3999 } | 4029 } |
| 4000 ConsumeToken(); | 4030 ConsumeToken(); |
| 4001 ExpectToken(Token::kLPAREN); | 4031 ExpectToken(Token::kLPAREN); |
| 4002 AstNode* cond_expr = ParseExpr(kAllowConst); | 4032 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4003 ExpectToken(Token::kRPAREN); | 4033 ExpectToken(Token::kRPAREN); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4016 if_node = sequence; | 4046 if_node = sequence; |
| 4017 } | 4047 } |
| 4018 return if_node; | 4048 return if_node; |
| 4019 } | 4049 } |
| 4020 | 4050 |
| 4021 | 4051 |
| 4022 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 4052 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 4023 SourceLabel* case_label) { | 4053 SourceLabel* case_label) { |
| 4024 TRACE_PARSER("ParseCaseStatement"); | 4054 TRACE_PARSER("ParseCaseStatement"); |
| 4025 bool default_seen = false; | 4055 bool default_seen = false; |
| 4026 intptr_t case_pos = token_index_; | 4056 const intptr_t case_pos = token_index_; |
| 4027 SequenceNode* case_expressions = | 4057 SequenceNode* case_expressions = |
| 4028 new SequenceNode(case_pos, current_block_->scope); | 4058 new SequenceNode(case_pos, current_block_->scope); |
| 4029 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 4059 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 4030 if (CurrentToken() == Token::kCASE) { | 4060 if (CurrentToken() == Token::kCASE) { |
| 4031 if (default_seen) { | 4061 if (default_seen) { |
| 4032 ErrorMsg("default clause must be last case"); | 4062 ErrorMsg("default clause must be last case"); |
| 4033 } | 4063 } |
| 4034 ConsumeToken(); // Keyword case. | 4064 ConsumeToken(); // Keyword case. |
| 4035 intptr_t expr_pos = token_index_; | 4065 const intptr_t expr_pos = token_index_; |
| 4036 AstNode* expr = ParseExpr(kAllowConst); | 4066 AstNode* expr = ParseExpr(kAllowConst); |
| 4037 AstNode* switch_expr_load = new LoadLocalNode(case_pos, | 4067 AstNode* switch_expr_load = new LoadLocalNode(case_pos, |
| 4038 *switch_expr_value); | 4068 *switch_expr_value); |
| 4039 AstNode* case_comparison = new ComparisonNode(expr_pos, | 4069 AstNode* case_comparison = new ComparisonNode(expr_pos, |
| 4040 Token::kEQ, | 4070 Token::kEQ, |
| 4041 expr, | 4071 expr, |
| 4042 switch_expr_load); | 4072 switch_expr_load); |
| 4043 case_expressions->Add(case_comparison); | 4073 case_expressions->Add(case_comparison); |
| 4044 } else { | 4074 } else { |
| 4045 if (default_seen) { | 4075 if (default_seen) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4090 } | 4120 } |
| 4091 SequenceNode* statements = CloseBlock(); | 4121 SequenceNode* statements = CloseBlock(); |
| 4092 return new CaseNode(case_pos, case_label, | 4122 return new CaseNode(case_pos, case_label, |
| 4093 case_expressions, default_seen, switch_expr_value, statements); | 4123 case_expressions, default_seen, switch_expr_value, statements); |
| 4094 } | 4124 } |
| 4095 | 4125 |
| 4096 | 4126 |
| 4097 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 4127 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 4098 TRACE_PARSER("ParseSwitchStatement"); | 4128 TRACE_PARSER("ParseSwitchStatement"); |
| 4099 ASSERT(CurrentToken() == Token::kSWITCH); | 4129 ASSERT(CurrentToken() == Token::kSWITCH); |
| 4100 intptr_t switch_pos = token_index_; | 4130 const intptr_t switch_pos = token_index_; |
| 4101 SourceLabel* label = | 4131 SourceLabel* label = |
| 4102 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 4132 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 4103 ConsumeToken(); | 4133 ConsumeToken(); |
| 4104 const bool parens_are_mandatory = false; | 4134 const bool parens_are_mandatory = false; |
| 4105 bool paren_found = false; | 4135 bool paren_found = false; |
| 4106 if (CurrentToken() == Token::kLPAREN) { | 4136 if (CurrentToken() == Token::kLPAREN) { |
| 4107 paren_found = true; | 4137 paren_found = true; |
| 4108 ConsumeToken(); | 4138 ConsumeToken(); |
| 4109 } else if (parens_are_mandatory) { | 4139 } else if (parens_are_mandatory) { |
| 4110 ErrorMsg("'(' expected"); | 4140 ErrorMsg("'(' expected"); |
| 4111 } | 4141 } |
| 4112 intptr_t expr_pos = token_index_; | 4142 const intptr_t expr_pos = token_index_; |
| 4113 AstNode* switch_expr = ParseExpr(kAllowConst); | 4143 AstNode* switch_expr = ParseExpr(kAllowConst); |
| 4114 if (paren_found) { | 4144 if (paren_found) { |
| 4115 ExpectToken(Token::kRPAREN); | 4145 ExpectToken(Token::kRPAREN); |
| 4116 } | 4146 } |
| 4117 ExpectToken(Token::kLBRACE); | 4147 ExpectToken(Token::kLBRACE); |
| 4118 OpenBlock(); | 4148 OpenBlock(); |
| 4119 current_block_->scope->AddLabel(label); | 4149 current_block_->scope->AddLabel(label); |
| 4120 | 4150 |
| 4121 // Store switch expression in temporary local variable. | 4151 // Store switch expression in temporary local variable. |
| 4122 LocalVariable* temp_variable = | 4152 LocalVariable* temp_variable = |
| 4123 new LocalVariable(expr_pos, | 4153 new LocalVariable(expr_pos, |
| 4124 String::ZoneHandle(String::NewSymbol(":switch_expr")), | 4154 String::ZoneHandle(String::NewSymbol(":switch_expr")), |
| 4125 Type::ZoneHandle(Type::DynamicType())); | 4155 Type::ZoneHandle(Type::DynamicType())); |
| 4126 current_block_->scope->AddVariable(temp_variable); | 4156 current_block_->scope->AddVariable(temp_variable); |
| 4127 AstNode* save_switch_expr = | 4157 AstNode* save_switch_expr = |
| 4128 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 4158 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
| 4129 current_block_->statements->Add(save_switch_expr); | 4159 current_block_->statements->Add(save_switch_expr); |
| 4130 | 4160 |
| 4131 // Parse case clauses | 4161 // Parse case clauses |
| 4132 bool default_seen = false; | 4162 bool default_seen = false; |
| 4133 while (true) { | 4163 while (true) { |
| 4134 // Check for statement label | 4164 // Check for statement label |
| 4135 SourceLabel* case_label = NULL; | 4165 SourceLabel* case_label = NULL; |
| 4136 if (CurrentToken() == Token::kIDENT && | 4166 if (CurrentToken() == Token::kIDENT && |
| 4137 LookaheadToken(1) == Token::kCOLON) { | 4167 LookaheadToken(1) == Token::kCOLON) { |
| 4138 // Case statements start with a label. | 4168 // Case statements start with a label. |
| 4139 String* label_name = CurrentLiteral(); | 4169 String* label_name = CurrentLiteral(); |
| 4140 intptr_t label_pos = token_index_; | 4170 const intptr_t label_pos = token_index_; |
| 4141 ConsumeToken(); // Consume label identifier. | 4171 ConsumeToken(); // Consume label identifier. |
| 4142 ConsumeToken(); // Consume colon. | 4172 ConsumeToken(); // Consume colon. |
| 4143 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 4173 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 4144 if (case_label == NULL) { | 4174 if (case_label == NULL) { |
| 4145 // Label does not exist yet. Add it to scope of switch statement. | 4175 // Label does not exist yet. Add it to scope of switch statement. |
| 4146 case_label = | 4176 case_label = |
| 4147 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); | 4177 new SourceLabel(label_pos, *label_name, SourceLabel::kCase); |
| 4148 current_block_->scope->AddLabel(case_label); | 4178 current_block_->scope->AddLabel(case_label); |
| 4149 } else if (case_label->kind() == SourceLabel::kForward) { | 4179 } else if (case_label->kind() == SourceLabel::kForward) { |
| 4150 // We have seen a 'continue' with this label name. Resolve | 4180 // We have seen a 'continue' with this label name. Resolve |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4182 } | 4212 } |
| 4183 | 4213 |
| 4184 SequenceNode* switch_body = CloseBlock(); | 4214 SequenceNode* switch_body = CloseBlock(); |
| 4185 ExpectToken(Token::kRBRACE); | 4215 ExpectToken(Token::kRBRACE); |
| 4186 return new SwitchNode(switch_pos, label, switch_body); | 4216 return new SwitchNode(switch_pos, label, switch_body); |
| 4187 } | 4217 } |
| 4188 | 4218 |
| 4189 | 4219 |
| 4190 AstNode* Parser::ParseWhileStatement(String* label_name) { | 4220 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 4191 TRACE_PARSER("ParseWhileStatement"); | 4221 TRACE_PARSER("ParseWhileStatement"); |
| 4192 intptr_t while_pos = token_index_; | 4222 const intptr_t while_pos = token_index_; |
| 4193 SourceLabel* label = | 4223 SourceLabel* label = |
| 4194 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 4224 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 4195 ConsumeToken(); | 4225 ConsumeToken(); |
| 4196 ExpectToken(Token::kLPAREN); | 4226 ExpectToken(Token::kLPAREN); |
| 4197 AstNode* cond_expr = ParseExpr(kAllowConst); | 4227 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4198 ExpectToken(Token::kRPAREN); | 4228 ExpectToken(Token::kRPAREN); |
| 4199 const bool parsing_loop_body = true; | 4229 const bool parsing_loop_body = true; |
| 4200 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 4230 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 4201 return new WhileNode(while_pos, label, cond_expr, while_body); | 4231 return new WhileNode(while_pos, label, cond_expr, while_body); |
| 4202 } | 4232 } |
| 4203 | 4233 |
| 4204 | 4234 |
| 4205 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 4235 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 4206 TRACE_PARSER("ParseDoWhileStatement"); | 4236 TRACE_PARSER("ParseDoWhileStatement"); |
| 4207 intptr_t do_pos = token_index_; | 4237 const intptr_t do_pos = token_index_; |
| 4208 SourceLabel* label = | 4238 SourceLabel* label = |
| 4209 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 4239 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 4210 ConsumeToken(); | 4240 ConsumeToken(); |
| 4211 const bool parsing_loop_body = true; | 4241 const bool parsing_loop_body = true; |
| 4212 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 4242 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 4213 ExpectToken(Token::kWHILE); | 4243 ExpectToken(Token::kWHILE); |
| 4214 ExpectToken(Token::kLPAREN); | 4244 ExpectToken(Token::kLPAREN); |
| 4215 AstNode* cond_expr = ParseExpr(kAllowConst); | 4245 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4216 ExpectToken(Token::kRPAREN); | 4246 ExpectToken(Token::kRPAREN); |
| 4217 ExpectSemicolon(); | 4247 ExpectSemicolon(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4233 const Type& type = Type::ZoneHandle( | 4263 const Type& type = Type::ZoneHandle( |
| 4234 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4264 ParseFinalVarOrType(kIsMandatory, kMustResolve)); |
| 4235 loop_var_pos = token_index_; | 4265 loop_var_pos = token_index_; |
| 4236 loop_var_name = ExpectIdentifier("variable name expected"); | 4266 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4237 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); | 4267 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); |
| 4238 if (is_final) { | 4268 if (is_final) { |
| 4239 loop_var->set_is_final(); | 4269 loop_var->set_is_final(); |
| 4240 } | 4270 } |
| 4241 } | 4271 } |
| 4242 ExpectToken(Token::kIN); | 4272 ExpectToken(Token::kIN); |
| 4243 intptr_t collection_pos = token_index_; | 4273 const intptr_t collection_pos = token_index_; |
| 4244 AstNode* collection_expr = ParseExpr(kAllowConst); | 4274 AstNode* collection_expr = ParseExpr(kAllowConst); |
| 4245 ExpectToken(Token::kRPAREN); | 4275 ExpectToken(Token::kRPAREN); |
| 4246 | 4276 |
| 4247 OpenBlock(); // Implicit block around while loop. | 4277 OpenBlock(); // Implicit block around while loop. |
| 4248 | 4278 |
| 4249 // Generate implicit iterator variable and add to scope. | 4279 // Generate implicit iterator variable and add to scope. |
| 4250 const String& iterator_name = | 4280 const String& iterator_name = |
| 4251 String::ZoneHandle(String::NewSymbol(":for-in-iter")); | 4281 String::ZoneHandle(String::NewSymbol(":for-in-iter")); |
| 4252 // We could set the type of the implicit iterator variable to Iterator<T> | 4282 // We could set the type of the implicit iterator variable to Iterator<T> |
| 4253 // where T is the type of the for loop variable. However, the type error | 4283 // where T is the type of the for loop variable. However, the type error |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4325 AstNode* while_statement = | 4355 AstNode* while_statement = |
| 4326 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); | 4356 new WhileNode(forin_pos, label, iterator_has_next, for_loop_statement); |
| 4327 current_block_->statements->Add(while_statement); | 4357 current_block_->statements->Add(while_statement); |
| 4328 | 4358 |
| 4329 return CloseBlock(); // Implicit block around while loop. | 4359 return CloseBlock(); // Implicit block around while loop. |
| 4330 } | 4360 } |
| 4331 | 4361 |
| 4332 | 4362 |
| 4333 AstNode* Parser::ParseForStatement(String* label_name) { | 4363 AstNode* Parser::ParseForStatement(String* label_name) { |
| 4334 TRACE_PARSER("ParseForStatement"); | 4364 TRACE_PARSER("ParseForStatement"); |
| 4335 intptr_t for_pos = token_index_; | 4365 const intptr_t for_pos = token_index_; |
| 4336 ConsumeToken(); | 4366 ConsumeToken(); |
| 4337 ExpectToken(Token::kLPAREN); | 4367 ExpectToken(Token::kLPAREN); |
| 4338 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 4368 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
| 4339 if (IsForInStatement()) { | 4369 if (IsForInStatement()) { |
| 4340 return ParseForInStatement(for_pos, label); | 4370 return ParseForInStatement(for_pos, label); |
| 4341 } | 4371 } |
| 4342 OpenBlock(); | 4372 OpenBlock(); |
| 4343 // The label is added to the implicit scope that also contains | 4373 // The label is added to the implicit scope that also contains |
| 4344 // the loop variable declarations. | 4374 // the loop variable declarations. |
| 4345 current_block_->scope->AddLabel(label); | 4375 current_block_->scope->AddLabel(label); |
| 4346 AstNode* initializer = NULL; | 4376 AstNode* initializer = NULL; |
| 4347 intptr_t init_pos = token_index_; | 4377 const intptr_t init_pos = token_index_; |
| 4348 LocalScope* init_scope = current_block_->scope; | 4378 LocalScope* init_scope = current_block_->scope; |
| 4349 if (CurrentToken() != Token::kSEMICOLON) { | 4379 if (CurrentToken() != Token::kSEMICOLON) { |
| 4350 if (IsVariableDeclaration()) { | 4380 if (IsVariableDeclaration()) { |
| 4351 initializer = ParseVariableDeclarationList(); | 4381 initializer = ParseVariableDeclarationList(); |
| 4352 } else { | 4382 } else { |
| 4353 initializer = ParseExpr(kAllowConst); | 4383 initializer = ParseExpr(kAllowConst); |
| 4354 } | 4384 } |
| 4355 } | 4385 } |
| 4356 ExpectSemicolon(); | 4386 ExpectSemicolon(); |
| 4357 AstNode* condition = NULL; | 4387 AstNode* condition = NULL; |
| 4358 if (CurrentToken() != Token::kSEMICOLON) { | 4388 if (CurrentToken() != Token::kSEMICOLON) { |
| 4359 condition = ParseExpr(kAllowConst); | 4389 condition = ParseExpr(kAllowConst); |
| 4360 } | 4390 } |
| 4361 ExpectSemicolon(); | 4391 ExpectSemicolon(); |
| 4362 AstNode* increment = NULL; | 4392 AstNode* increment = NULL; |
| 4363 intptr_t incr_pos = token_index_; | 4393 const intptr_t incr_pos = token_index_; |
| 4364 LocalScope* incr_scope = current_block_->scope; | 4394 LocalScope* incr_scope = current_block_->scope; |
| 4365 if (CurrentToken() != Token::kRPAREN) { | 4395 if (CurrentToken() != Token::kRPAREN) { |
| 4366 increment = ParseExprList(); | 4396 increment = ParseExprList(); |
| 4367 } | 4397 } |
| 4368 ExpectToken(Token::kRPAREN); | 4398 ExpectToken(Token::kRPAREN); |
| 4369 const bool parsing_loop_body = true; | 4399 const bool parsing_loop_body = true; |
| 4370 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); | 4400 SequenceNode* body = ParseNestedStatement(parsing_loop_body, NULL); |
| 4371 | 4401 |
| 4372 // Check whether any of the variables in the initializer part of | 4402 // Check whether any of the variables in the initializer part of |
| 4373 // the for statement are captured by a closure. If so, we insert a | 4403 // the for statement are captured by a closure. If so, we insert a |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4621 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); | 4651 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); |
| 4622 LocalVariable* catch_trace_var = | 4652 LocalVariable* catch_trace_var = |
| 4623 current_block_->scope->LocalLookupVariable(catch_trace_var_name); | 4653 current_block_->scope->LocalLookupVariable(catch_trace_var_name); |
| 4624 if (catch_trace_var == NULL) { | 4654 if (catch_trace_var == NULL) { |
| 4625 catch_trace_var = new LocalVariable(token_index_, | 4655 catch_trace_var = new LocalVariable(token_index_, |
| 4626 catch_trace_var_name, | 4656 catch_trace_var_name, |
| 4627 Type::ZoneHandle(Type::DynamicType())); | 4657 Type::ZoneHandle(Type::DynamicType())); |
| 4628 current_block_->scope->AddVariable(catch_trace_var); | 4658 current_block_->scope->AddVariable(catch_trace_var); |
| 4629 } | 4659 } |
| 4630 | 4660 |
| 4631 intptr_t try_pos = token_index_; | 4661 const intptr_t try_pos = token_index_; |
| 4632 ConsumeToken(); // Consume the 'try'. | 4662 ConsumeToken(); // Consume the 'try'. |
| 4633 | 4663 |
| 4634 SourceLabel* try_label = NULL; | 4664 SourceLabel* try_label = NULL; |
| 4635 if (label_name != NULL) { | 4665 if (label_name != NULL) { |
| 4636 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 4666 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 4637 OpenBlock(); | 4667 OpenBlock(); |
| 4638 current_block_->scope->AddLabel(try_label); | 4668 current_block_->scope->AddLabel(try_label); |
| 4639 } | 4669 } |
| 4640 | 4670 |
| 4641 // Now parse the 'try' block. | 4671 // Now parse the 'try' block. |
| 4642 OpenBlock(); | 4672 OpenBlock(); |
| 4643 Block* current_try_block = current_block_; | 4673 Block* current_try_block = current_block_; |
| 4644 PushTryBlock(current_try_block); | 4674 PushTryBlock(current_try_block); |
| 4645 ExpectToken(Token::kLBRACE); | 4675 ExpectToken(Token::kLBRACE); |
| 4646 ParseStatementSequence(); | 4676 ParseStatementSequence(); |
| 4647 ExpectToken(Token::kRBRACE); | 4677 ExpectToken(Token::kRBRACE); |
| 4648 SequenceNode* try_block = CloseBlock(); | 4678 SequenceNode* try_block = CloseBlock(); |
| 4649 | 4679 |
| 4650 // Now create a label for the end of catch block processing so that we can | 4680 // Now create a label for the end of catch block processing so that we can |
| 4651 // jump over the catch block code after executing the try block. | 4681 // jump over the catch block code after executing the try block. |
| 4652 SourceLabel* end_catch_label = | 4682 SourceLabel* end_catch_label = |
| 4653 SourceLabel::New(token_index_, NULL, SourceLabel::kCatch); | 4683 SourceLabel::New(token_index_, NULL, SourceLabel::kCatch); |
| 4654 | 4684 |
| 4655 // Now parse the 'catch' blocks if any and merge all of them into | 4685 // Now parse the 'catch' blocks if any and merge all of them into |
| 4656 // an if-then sequence of the different types specified using the 'is' | 4686 // an if-then sequence of the different types specified using the 'is' |
| 4657 // operator. | 4687 // operator. |
| 4658 bool catch_seen = false; | 4688 bool catch_seen = false; |
| 4659 bool generic_catch_seen = false; | 4689 bool generic_catch_seen = false; |
| 4660 SequenceNode* catch_handler_list = NULL; | 4690 SequenceNode* catch_handler_list = NULL; |
| 4661 intptr_t handler_pos = token_index_; | 4691 const intptr_t handler_pos = token_index_; |
| 4662 OpenBlock(); // Start the catch block sequence. | 4692 OpenBlock(); // Start the catch block sequence. |
| 4663 current_block_->scope->AddLabel(end_catch_label); | 4693 current_block_->scope->AddLabel(end_catch_label); |
| 4664 while (CurrentToken() == Token::kCATCH) { | 4694 while (CurrentToken() == Token::kCATCH) { |
| 4665 catch_seen = true; | 4695 catch_seen = true; |
| 4666 intptr_t catch_pos = token_index_; | 4696 const intptr_t catch_pos = token_index_; |
| 4667 ConsumeToken(); // Consume the 'catch'. | 4697 ConsumeToken(); // Consume the 'catch'. |
| 4668 ExpectToken(Token::kLPAREN); | 4698 ExpectToken(Token::kLPAREN); |
| 4669 CatchParamDesc exception_param; | 4699 CatchParamDesc exception_param; |
| 4670 CatchParamDesc stack_trace_param; | 4700 CatchParamDesc stack_trace_param; |
| 4671 ParseCatchParameter(&exception_param); | 4701 ParseCatchParameter(&exception_param); |
| 4672 if (CurrentToken() == Token::kCOMMA) { | 4702 if (CurrentToken() == Token::kCOMMA) { |
| 4673 ConsumeToken(); | 4703 ConsumeToken(); |
| 4674 ParseCatchParameter(&stack_trace_param); | 4704 ParseCatchParameter(&stack_trace_param); |
| 4675 } | 4705 } |
| 4676 ExpectToken(Token::kRPAREN); | 4706 ExpectToken(Token::kRPAREN); |
| 4677 | 4707 |
| 4678 // If a generic "catch all" statement has already been seen then all | 4708 // If a generic "catch all" statement has already been seen then all |
| 4679 // subsequent catch statements are dead. We issue an error for now, | 4709 // subsequent catch statements are dead. We issue an error for now, |
| 4680 // it might make sense to turn this into a warning. | 4710 // it might make sense to turn this into a warning. |
| 4681 if (generic_catch_seen) { | 4711 if (generic_catch_seen) { |
| 4682 ErrorMsg("A generic 'catch all' statement already exists for this " | 4712 ErrorMsg("a generic 'catch all' statement already exists for this " |
| 4683 "try block. All subsequent catch statements are dead code"); | 4713 "try block. All subsequent catch statements are dead code"); |
| 4684 } | 4714 } |
| 4685 OpenBlock(); | 4715 OpenBlock(); |
| 4686 AddCatchParamsToScope(exception_param, | 4716 AddCatchParamsToScope(exception_param, |
| 4687 stack_trace_param, | 4717 stack_trace_param, |
| 4688 current_block_->scope); | 4718 current_block_->scope); |
| 4689 | 4719 |
| 4690 SequenceNode* catch_clause; | 4720 SequenceNode* catch_clause; |
| 4691 | 4721 |
| 4692 // Parse the individual catch handler code and add an unconditional | 4722 // Parse the individual catch handler code and add an unconditional |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4748 current_block_->statements->Add(catch_clause); | 4778 current_block_->statements->Add(catch_clause); |
| 4749 } | 4779 } |
| 4750 catch_handler_list = CloseBlock(); | 4780 catch_handler_list = CloseBlock(); |
| 4751 TryBlocks* inner_try_block = PopTryBlock(); | 4781 TryBlocks* inner_try_block = PopTryBlock(); |
| 4752 | 4782 |
| 4753 // Finally parse the 'finally' block. | 4783 // Finally parse the 'finally' block. |
| 4754 SequenceNode* finally_block = NULL; | 4784 SequenceNode* finally_block = NULL; |
| 4755 if (CurrentToken() == Token::kFINALLY) { | 4785 if (CurrentToken() == Token::kFINALLY) { |
| 4756 current_function_.set_is_optimizable(false); | 4786 current_function_.set_is_optimizable(false); |
| 4757 ConsumeToken(); // Consume the 'finally'. | 4787 ConsumeToken(); // Consume the 'finally'. |
| 4758 intptr_t finally_pos = token_index_; | 4788 const intptr_t finally_pos = token_index_; |
| 4759 // Add the finally block to the exit points recorded so far. | 4789 // Add the finally block to the exit points recorded so far. |
| 4760 intptr_t node_index = 0; | 4790 intptr_t node_index = 0; |
| 4761 AstNode* node_to_inline = | 4791 AstNode* node_to_inline = |
| 4762 inner_try_block->GetNodeToInlineFinally(node_index); | 4792 inner_try_block->GetNodeToInlineFinally(node_index); |
| 4763 while (node_to_inline != NULL) { | 4793 while (node_to_inline != NULL) { |
| 4764 finally_block = ParseFinallyBlock(); | 4794 finally_block = ParseFinallyBlock(); |
| 4765 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, | 4795 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, |
| 4766 finally_block, | 4796 finally_block, |
| 4767 *context_var); | 4797 *context_var); |
| 4768 AddFinallyBlockToNode(node_to_inline, node); | 4798 AddFinallyBlockToNode(node_to_inline, node); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4811 sequence->set_label(try_label); | 4841 sequence->set_label(try_label); |
| 4812 try_catch_node = sequence; | 4842 try_catch_node = sequence; |
| 4813 } | 4843 } |
| 4814 return try_catch_node; | 4844 return try_catch_node; |
| 4815 } | 4845 } |
| 4816 | 4846 |
| 4817 | 4847 |
| 4818 AstNode* Parser::ParseJump(String* label_name) { | 4848 AstNode* Parser::ParseJump(String* label_name) { |
| 4819 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 4849 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 4820 Token::Kind jump_kind = CurrentToken(); | 4850 Token::Kind jump_kind = CurrentToken(); |
| 4821 intptr_t jump_pos = token_index_; | 4851 const intptr_t jump_pos = token_index_; |
| 4822 SourceLabel* target = NULL; | 4852 SourceLabel* target = NULL; |
| 4823 ConsumeToken(); | 4853 ConsumeToken(); |
| 4824 if (CurrentToken() == Token::kIDENT) { | 4854 if (CurrentToken() == Token::kIDENT) { |
| 4825 // Explicit label after break/continue. | 4855 // Explicit label after break/continue. |
| 4826 const String& target_name = *CurrentLiteral(); | 4856 const String& target_name = *CurrentLiteral(); |
| 4827 ConsumeToken(); | 4857 ConsumeToken(); |
| 4828 // Handle pathological cases first. | 4858 // Handle pathological cases first. |
| 4829 if (label_name != NULL && target_name.Equals(*label_name)) { | 4859 if (label_name != NULL && target_name.Equals(*label_name)) { |
| 4830 if (jump_kind == Token::kCONTINUE) { | 4860 if (jump_kind == Token::kCONTINUE) { |
| 4831 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 4861 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5034 | 5064 |
| 5035 | 5065 |
| 5036 void Parser::Warning(const char* format, ...) { | 5066 void Parser::Warning(const char* format, ...) { |
| 5037 if (FLAG_silent_warnings) return; | 5067 if (FLAG_silent_warnings) return; |
| 5038 va_list args; | 5068 va_list args; |
| 5039 va_start(args, format); | 5069 va_start(args, format); |
| 5040 ReportMsg(script_, token_index_, "Warning", error_msg_, format, args); | 5070 ReportMsg(script_, token_index_, "Warning", error_msg_, format, args); |
| 5041 if (FLAG_warning_as_error) { | 5071 if (FLAG_warning_as_error) { |
| 5042 Isolate::Current()->long_jump_base()->Jump(1, error_msg_); | 5072 Isolate::Current()->long_jump_base()->Jump(1, error_msg_); |
| 5043 UNREACHABLE(); | 5073 UNREACHABLE(); |
| 5074 } else { |
| 5075 OS::Print(error_msg_); |
| 5044 } | 5076 } |
| 5045 } | 5077 } |
| 5046 | 5078 |
| 5047 | 5079 |
| 5048 void Parser::Unimplemented(const char* msg) { | 5080 void Parser::Unimplemented(const char* msg) { |
| 5049 ErrorMsg(token_index_, msg); | 5081 ErrorMsg(token_index_, msg); |
| 5050 } | 5082 } |
| 5051 | 5083 |
| 5052 | 5084 |
| 5053 void Parser::ExpectToken(Token::Kind token_expected) { | 5085 void Parser::ExpectToken(Token::Kind token_expected) { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5331 return new BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); | 5363 return new BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); |
| 5332 case Token::kASSIGN_SHR: | 5364 case Token::kASSIGN_SHR: |
| 5333 return new BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); | 5365 return new BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); |
| 5334 case Token::kASSIGN_OR: | 5366 case Token::kASSIGN_OR: |
| 5335 return new BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); | 5367 return new BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); |
| 5336 case Token::kASSIGN_AND: | 5368 case Token::kASSIGN_AND: |
| 5337 return new BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); | 5369 return new BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); |
| 5338 case Token::kASSIGN_XOR: | 5370 case Token::kASSIGN_XOR: |
| 5339 return new BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); | 5371 return new BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); |
| 5340 default: | 5372 default: |
| 5341 ErrorMsg(op_pos, "Internal error: ExpandAssignableOp '%s' unimplemented", | 5373 ErrorMsg(op_pos, "internal error: ExpandAssignableOp '%s' unimplemented", |
| 5342 Token::Name(assignment_op)); | 5374 Token::Name(assignment_op)); |
| 5343 UNIMPLEMENTED(); | 5375 UNIMPLEMENTED(); |
| 5344 return NULL; | 5376 return NULL; |
| 5345 } | 5377 } |
| 5346 } | 5378 } |
| 5347 | 5379 |
| 5348 | 5380 |
| 5349 // Evaluates the value of the compile time constant expression | 5381 // Evaluates the value of the compile time constant expression |
| 5350 // and returns a literal node for the value. | 5382 // and returns a literal node for the value. |
| 5351 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 5383 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 5379 } | 5411 } |
| 5380 AstNode* right_expr = ParseExpr(require_compiletime_const); | 5412 AstNode* right_expr = ParseExpr(require_compiletime_const); |
| 5381 if (assignment_op != Token::kASSIGN) { | 5413 if (assignment_op != Token::kASSIGN) { |
| 5382 expr = AsSideEffectFreeNode(expr); | 5414 expr = AsSideEffectFreeNode(expr); |
| 5383 } | 5415 } |
| 5384 right_expr = | 5416 right_expr = |
| 5385 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 5417 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 5386 AstNode* assign_expr = expr->MakeAssignmentNode(right_expr); | 5418 AstNode* assign_expr = expr->MakeAssignmentNode(right_expr); |
| 5387 if (assign_expr == NULL) { | 5419 if (assign_expr == NULL) { |
| 5388 ErrorMsg(assignment_pos, | 5420 ErrorMsg(assignment_pos, |
| 5389 "Left hand side of '%s' is not assignable", | 5421 "left hand side of '%s' is not assignable", |
| 5390 Token::Str(assignment_op)); | 5422 Token::Str(assignment_op)); |
| 5391 } | 5423 } |
| 5392 return assign_expr; | 5424 return assign_expr; |
| 5393 } | 5425 } |
| 5394 | 5426 |
| 5395 | 5427 |
| 5396 LiteralNode* Parser::ParseConstExpr() { | 5428 LiteralNode* Parser::ParseConstExpr() { |
| 5397 TRACE_PARSER("ParseConstExpr"); | 5429 TRACE_PARSER("ParseConstExpr"); |
| 5398 AstNode* expr = ParseExpr(kRequireConst); | 5430 AstNode* expr = ParseExpr(kRequireConst); |
| 5399 ASSERT(expr->IsLiteralNode()); | 5431 ASSERT(expr->IsLiteralNode()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5423 if (IsPrefixOperator(CurrentToken())) { | 5455 if (IsPrefixOperator(CurrentToken())) { |
| 5424 Token::Kind unary_op = CurrentToken(); | 5456 Token::Kind unary_op = CurrentToken(); |
| 5425 ConsumeToken(); | 5457 ConsumeToken(); |
| 5426 expr = ParseUnaryExpr(); | 5458 expr = ParseUnaryExpr(); |
| 5427 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 5459 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 5428 } else if (IsIncrementOperator(CurrentToken())) { | 5460 } else if (IsIncrementOperator(CurrentToken())) { |
| 5429 Token::Kind incr_op = CurrentToken(); | 5461 Token::Kind incr_op = CurrentToken(); |
| 5430 ConsumeToken(); | 5462 ConsumeToken(); |
| 5431 expr = ParseUnaryExpr(); | 5463 expr = ParseUnaryExpr(); |
| 5432 if (!IsAssignableExpr(expr)) { | 5464 if (!IsAssignableExpr(expr)) { |
| 5433 ErrorMsg("Expression is not assignable"); | 5465 ErrorMsg("expression is not assignable"); |
| 5434 } | 5466 } |
| 5435 // is_prefix. | 5467 // is_prefix. |
| 5436 AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true); | 5468 AstNode* incr_op_node = expr->MakeIncrOpNode(op_pos, incr_op, true); |
| 5437 if (incr_op_node == NULL) { | 5469 if (incr_op_node == NULL) { |
| 5438 Unimplemented("incr operation not implemented"); | 5470 Unimplemented("incr operation not implemented"); |
| 5439 } | 5471 } |
| 5440 expr = incr_op_node; | 5472 expr = incr_op_node; |
| 5441 } else { | 5473 } else { |
| 5442 expr = ParsePostfixExpr(); | 5474 expr = ParsePostfixExpr(); |
| 5443 } | 5475 } |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5774 Function& func = Function::CheckedHandle(primary->primary().raw()); | 5806 Function& func = Function::CheckedHandle(primary->primary().raw()); |
| 5775 String& func_name = String::ZoneHandle(func.name()); | 5807 String& func_name = String::ZoneHandle(func.name()); |
| 5776 if (func.is_static()) { | 5808 if (func.is_static()) { |
| 5777 // Parse static function call. | 5809 // Parse static function call. |
| 5778 Class& cls = Class::Handle(func.owner()); | 5810 Class& cls = Class::Handle(func.owner()); |
| 5779 selector = ParseStaticCall(cls, func_name, primary_pos); | 5811 selector = ParseStaticCall(cls, func_name, primary_pos); |
| 5780 } else { | 5812 } else { |
| 5781 // Dynamic function call on implicit "this" parameter. | 5813 // Dynamic function call on implicit "this" parameter. |
| 5782 if (current_function().is_static()) { | 5814 if (current_function().is_static()) { |
| 5783 ErrorMsg(primary_pos, | 5815 ErrorMsg(primary_pos, |
| 5784 "Cannot access instance method '%s' " | 5816 "cannot access instance method '%s' " |
| 5785 "from static function", | 5817 "from static function", |
| 5786 func_name.ToCString()); | 5818 func_name.ToCString()); |
| 5787 } | 5819 } |
| 5788 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); | 5820 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); |
| 5789 } | 5821 } |
| 5790 } else if (primary->primary().IsString()) { | 5822 } else if (primary->primary().IsString()) { |
| 5791 // Primary is an unresolved name. | 5823 // Primary is an unresolved name. |
| 5792 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 5824 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
| 5793 if (current_function().is_static()) { | 5825 if (current_function().is_static()) { |
| 5794 ErrorMsg(primary->token_index(), | 5826 ErrorMsg(primary->token_index(), |
| 5795 "identifier '%s' is not declared in this scope", | 5827 "identifier '%s' is not declared in this scope", |
| 5796 name.ToCString()); | 5828 name.ToCString()); |
| 5797 } else { | 5829 } else { |
| 5798 // Treat as call to unresolved (instance) method. | 5830 // Treat as call to unresolved (instance) method. |
| 5799 AstNode* receiver = LoadReceiver(primary->token_index()); | 5831 AstNode* receiver = LoadReceiver(primary->token_index()); |
| 5800 selector = ParseInstanceCall(receiver, name); | 5832 selector = ParseInstanceCall(receiver, name); |
| 5801 } | 5833 } |
| 5802 } else if (primary->primary().IsClass()) { | 5834 } else if (primary->primary().IsClass()) { |
| 5803 ErrorMsg(left->token_index(), | 5835 ErrorMsg(left->token_index(), |
| 5804 "must use 'new' or 'const' to construct new instance"); | 5836 "must use 'new' or 'const' to construct new instance"); |
| 5805 } else { | 5837 } else { |
| 5806 // Internal parser error. | 5838 // Internal parser error. |
| 5807 UNREACHABLE(); | 5839 UNREACHABLE(); |
| 5808 } | 5840 } |
| 5809 } else { | 5841 } else { |
| 5810 // Left is not a primary node; this must be a closure call. | 5842 // Left is not a primary node; this must be a closure call. |
| 5811 AstNode* closure = left; | 5843 AstNode* closure = left; |
| 5812 selector = ParseClosureCall(closure); | 5844 selector = ParseClosureCall(closure); |
| 5813 } | 5845 } |
| 5814 } else { | 5846 } else { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5875 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); | 5907 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); |
| 5876 if (incr_op_node == NULL) { | 5908 if (incr_op_node == NULL) { |
| 5877 Unimplemented("incr op not implemented"); | 5909 Unimplemented("incr op not implemented"); |
| 5878 } | 5910 } |
| 5879 postfix_expr = incr_op_node; | 5911 postfix_expr = incr_op_node; |
| 5880 } | 5912 } |
| 5881 return postfix_expr; | 5913 return postfix_expr; |
| 5882 } | 5914 } |
| 5883 | 5915 |
| 5884 | 5916 |
| 5885 bool Parser::ResolveTypeFromClass(intptr_t type_pos, | 5917 // Try to resolve the given type and its type arguments from the given class. |
| 5886 const Class& cls, | 5918 // Not all involved type classes may get resolved yet, but at least the type |
| 5887 Type* type) { | 5919 // parameters of the given class will get resolved, thereby relieving the class |
| 5920 // finalizer from resolving type parameters out of context. |
| 5921 void Parser::TryResolveTypeFromClass(intptr_t type_pos, |
| 5922 const Class& cls, |
| 5923 Type* type) { |
| 5888 ASSERT(type != NULL); | 5924 ASSERT(type != NULL); |
| 5889 // Resolve class. | 5925 // Resolve class. |
| 5890 if (!type->HasResolvedTypeClass()) { | 5926 if (!type->HasResolvedTypeClass()) { |
| 5891 const UnresolvedClass& unresolved_class = | 5927 const UnresolvedClass& unresolved_class = |
| 5892 UnresolvedClass::Handle(type->unresolved_class()); | 5928 UnresolvedClass::Handle(type->unresolved_class()); |
| 5893 const String& unresolved_class_name = | 5929 const String& unresolved_class_name = |
| 5894 String::Handle(unresolved_class.ident()); | 5930 String::Handle(unresolved_class.ident()); |
| 5895 // First check if the type is a type parameter of the given class. | 5931 // First check if the type is a type parameter of the given class. |
| 5896 const TypeParameter& type_parameter = TypeParameter::Handle( | 5932 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 5897 cls.LookupTypeParameter(unresolved_class_name)); | 5933 cls.LookupTypeParameter(unresolved_class_name)); |
| 5898 if (!type_parameter.IsNull()) { | 5934 if (!type_parameter.IsNull()) { |
| 5899 CheckTypeParameterReference(type_pos, unresolved_class_name); | |
| 5900 // A type parameter cannot be parameterized, so report an error if type | 5935 // A type parameter cannot be parameterized, so report an error if type |
| 5901 // arguments have previously been parsed. | 5936 // arguments have previously been parsed. |
| 5902 if (type->arguments() != TypeArguments::null()) { | 5937 if (type->arguments() != TypeArguments::null()) { |
| 5903 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", | 5938 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", |
| 5904 type_parameter.ToCString()); | 5939 type_parameter.ToCString()); |
| 5905 return false; | |
| 5906 } | 5940 } |
| 5907 *type = type_parameter.raw(); | 5941 *type = type_parameter.raw(); |
| 5908 return true; | 5942 return; |
| 5909 } | 5943 } |
| 5910 const Class& resolved_type_class = | 5944 const Class& resolved_type_class = |
| 5911 Class::Handle(LookupClass(unresolved_class_name)); | 5945 Class::Handle(LookupClass(unresolved_class_name)); |
| 5912 if (resolved_type_class.IsNull()) { | 5946 if (!resolved_type_class.IsNull()) { |
| 5913 return false; | 5947 Object& type_class = Object::Handle(resolved_type_class.raw()); |
| 5948 ASSERT(type->IsParameterizedType()); |
| 5949 // Replace unresolved class with resolved type class. |
| 5950 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 5951 parameterized_type ^= type->raw(); |
| 5952 parameterized_type.set_type_class(type_class); |
| 5914 } | 5953 } |
| 5915 Object& type_class = Object::Handle(resolved_type_class.raw()); | |
| 5916 ASSERT(type->IsParameterizedType()); | |
| 5917 // Replace unresolved class with resolved type class. | |
| 5918 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | |
| 5919 parameterized_type ^= type->raw(); | |
| 5920 parameterized_type.set_type_class(type_class); | |
| 5921 } | 5954 } |
| 5922 // Resolve type arguments, if any. | 5955 // Resolve type arguments, if any. |
| 5923 const TypeArguments& arguments = TypeArguments::Handle(type->arguments()); | 5956 const TypeArguments& arguments = TypeArguments::Handle(type->arguments()); |
| 5924 if (!arguments.IsNull()) { | 5957 if (!arguments.IsNull()) { |
| 5925 intptr_t num_arguments = arguments.Length(); | 5958 const intptr_t num_arguments = arguments.Length(); |
| 5926 for (intptr_t i = 0; i < num_arguments; i++) { | 5959 for (intptr_t i = 0; i < num_arguments; i++) { |
| 5927 Type& type_argument = Type::Handle(arguments.TypeAt(i)); | 5960 Type& type_argument = Type::Handle(arguments.TypeAt(i)); |
| 5928 if (!ResolveTypeFromClass(type_pos, cls, &type_argument)) { | 5961 TryResolveTypeFromClass(type_pos, cls, &type_argument); |
| 5929 return false; | |
| 5930 } | |
| 5931 arguments.SetTypeAt(i, type_argument); | 5962 arguments.SetTypeAt(i, type_argument); |
| 5932 } | 5963 } |
| 5933 } | 5964 } |
| 5934 return true; | |
| 5935 } | 5965 } |
| 5936 | 5966 |
| 5937 | 5967 |
| 5938 // Return class for type name. If the name cannot be resolved (yet), give an | 5968 // Return class for type name. If the name cannot be resolved (yet), give an |
| 5939 // error (if type_resolution == kMustResolve) or return the unresolved name. | 5969 // error (if type_resolution == kMustResolve) or return the unresolved name. |
| 5940 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, | 5970 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, |
| 5941 TypeResolution type_resolution) { | 5971 TypeResolution type_resolution) { |
| 5942 ASSERT(type_name.ident != NULL); | 5972 ASSERT(type_name.ident != NULL); |
| 5943 Class& type_class = Class::Handle(); | 5973 Class& type_class = Class::Handle(); |
| 5944 if (type_name.lib_prefix != NULL) { | 5974 if (type_name.lib_prefix != NULL) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5983 // Fields are not accessible from a static function, except from a | 6013 // Fields are not accessible from a static function, except from a |
| 5984 // constructor, which is considered as non-static by the compiler. | 6014 // constructor, which is considered as non-static by the compiler. |
| 5985 if (current_function().is_static()) { | 6015 if (current_function().is_static()) { |
| 5986 ErrorMsg(field_pos, | 6016 ErrorMsg(field_pos, |
| 5987 "cannot access instance field '%s' from a static function", | 6017 "cannot access instance field '%s' from a static function", |
| 5988 field_name.ToCString()); | 6018 field_name.ToCString()); |
| 5989 } | 6019 } |
| 5990 } | 6020 } |
| 5991 | 6021 |
| 5992 | 6022 |
| 5993 void Parser::CheckTypeParameterReference(intptr_t type_parameter_pos, | 6023 // If type parameters are currently in scope, return their declaring class, |
| 5994 const String& type_parameter_name) { | 6024 // otherwise return null. |
| 6025 RawClass* Parser::TypeParametersScopeClass() { |
| 5995 // Type parameters cannot be referred to from a static function, except from | 6026 // Type parameters cannot be referred to from a static function, except from |
| 5996 // a constructor or from a factory. | 6027 // a constructor or from a factory. |
| 5997 // A constructor is considered as non-static by the compiler. | 6028 // A constructor is considered as non-static by the compiler. |
| 5998 if ((is_top_level_ && | 6029 if (is_top_level_) { |
| 5999 (current_member_ != NULL) && | 6030 if ((current_member_ != NULL) && current_member_->has_factory) { |
| 6000 current_member_->has_static && | 6031 const Type& factory_result_type = *current_member_->type; |
| 6001 !current_member_->has_factory) || | 6032 ASSERT(!factory_result_type.IsNull()); |
| 6002 (!current_function().IsNull() && | 6033 const UnresolvedClass& unresolved_factory_class = |
| 6003 current_function().is_static() && | 6034 UnresolvedClass::Handle(factory_result_type.unresolved_class()); |
| 6004 !current_function().IsInFactoryScope())) { | 6035 // TODO(regis): For now, and until the core lib is fixed, we accept a |
| 6005 ErrorMsg(type_parameter_pos, | 6036 // factory method with missing list of type parameters and use the |
| 6006 "cannot refer to type parameter '%s' from a static function", | 6037 // list of the enclosing class. |
| 6007 type_parameter_name.ToCString()); | 6038 // See bug 5408808. |
| 6039 // Therefore, we temporarily return the current class instead of the |
| 6040 // factory signature class if the latter one does not declare any type |
| 6041 // parameters. |
| 6042 const Class& factory_signature_class = |
| 6043 Class::Handle(unresolved_factory_class.factory_signature_class()); |
| 6044 if (factory_signature_class.NumTypeParameters() == 0) { |
| 6045 return current_class().raw(); |
| 6046 } else { |
| 6047 return factory_signature_class.raw(); |
| 6048 } |
| 6049 } |
| 6050 if ((current_member_ == NULL) || !current_member_->has_static) { |
| 6051 return current_class().raw(); |
| 6052 } |
| 6053 } else { |
| 6054 if (!current_function().IsNull()) { |
| 6055 Function& outer_function = Function::Handle(current_function().raw()); |
| 6056 while (outer_function.IsLocalFunction()) { |
| 6057 outer_function = outer_function.parent_function(); |
| 6058 } |
| 6059 if (outer_function.IsFactory()) { |
| 6060 return outer_function.signature_class(); |
| 6061 } |
| 6062 if (!outer_function.is_static()) { |
| 6063 return current_class().raw(); |
| 6064 } |
| 6065 } |
| 6008 } | 6066 } |
| 6067 return Class::null(); |
| 6009 } | 6068 } |
| 6010 | 6069 |
| 6011 | 6070 |
| 6012 void Parser::RunStaticFieldInitializer(const Field& field) { | 6071 void Parser::RunStaticFieldInitializer(const Field& field) { |
| 6013 ASSERT(field.is_static()); | 6072 ASSERT(field.is_static()); |
| 6014 const Instance& value = Instance::Handle(field.value()); | 6073 const Instance& value = Instance::Handle(field.value()); |
| 6015 if (value.raw() == Object::transition_sentinel()) { | 6074 if (value.raw() == Object::transition_sentinel()) { |
| 6016 ErrorMsg("Circular dependency while initializing static field '%s'", | 6075 ErrorMsg("circular dependency while initializing static field '%s'", |
| 6017 String::Handle(field.name()).ToCString()); | 6076 String::Handle(field.name()).ToCString()); |
| 6018 | 6077 |
| 6019 } else if (value.raw() == Object::sentinel()) { | 6078 } else if (value.raw() == Object::sentinel()) { |
| 6020 // This field has not been referenced yet and thus the value has | 6079 // This field has not been referenced yet and thus the value has |
| 6021 // not been evaluated. Call the static getter method to evaluate | 6080 // not been evaluated. Call the static getter method to evaluate |
| 6022 // the expression and canonicalize the value. | 6081 // the expression and canonicalize the value. |
| 6023 | 6082 |
| 6024 field.set_value(Instance::Handle(Object::transition_sentinel())); | 6083 field.set_value(Instance::Handle(Object::transition_sentinel())); |
| 6025 const String& field_name = String::Handle(field.name()); | 6084 const String& field_name = String::Handle(field.name()); |
| 6026 const String& getter_name = | 6085 const String& getter_name = |
| 6027 String::Handle(Field::GetterName(field_name)); | 6086 String::Handle(Field::GetterName(field_name)); |
| 6028 const Class& cls = Class::Handle(field.owner()); | 6087 const Class& cls = Class::Handle(field.owner()); |
| 6029 GrowableArray<const Object*> arguments; // no arguments. | 6088 GrowableArray<const Object*> arguments; // no arguments. |
| 6030 const int kNumArguments = 0; // no arguments. | 6089 const int kNumArguments = 0; // no arguments. |
| 6031 const Array& kNoArgumentNames = Array::Handle(); | 6090 const Array& kNoArgumentNames = Array::Handle(); |
| 6032 const Function& func = | 6091 const Function& func = |
| 6033 Function::Handle(Resolver::ResolveStatic(cls, | 6092 Function::Handle(Resolver::ResolveStatic(cls, |
| 6034 getter_name, | 6093 getter_name, |
| 6035 kNumArguments, | 6094 kNumArguments, |
| 6036 kNoArgumentNames, | 6095 kNoArgumentNames, |
| 6037 Resolver::kIsQualified)); | 6096 Resolver::kIsQualified)); |
| 6038 ASSERT(!func.IsNull()); | 6097 ASSERT(!func.IsNull()); |
| 6039 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); | 6098 ASSERT(func.kind() == RawFunction::kConstImplicitGetter); |
| 6040 Instance& const_value = Instance::Handle( | 6099 Instance& const_value = Instance::Handle( |
| 6041 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); | 6100 DartEntry::InvokeStatic(func, arguments, kNoArgumentNames)); |
| 6042 if (const_value.IsUnhandledException()) { | 6101 if (const_value.IsUnhandledException()) { |
| 6043 ErrorMsg("Exception thrown in Parser::RunStaticFieldInitializer"); | 6102 ErrorMsg("exception thrown in Parser::RunStaticFieldInitializer"); |
| 6044 } | 6103 } |
| 6045 if (!const_value.IsNull()) { | 6104 if (!const_value.IsNull()) { |
| 6046 const_value ^= const_value.Canonicalize(); | 6105 const_value ^= const_value.Canonicalize(); |
| 6047 } | 6106 } |
| 6048 field.set_value(const_value); | 6107 field.set_value(const_value); |
| 6049 } | 6108 } |
| 6050 } | 6109 } |
| 6051 | 6110 |
| 6052 | 6111 |
| 6053 RawInstance* Parser::EvaluateConstConstructorCall( | 6112 RawInstance* Parser::EvaluateConstConstructorCall( |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6332 | 6391 |
| 6333 // Parses type = [ident "."] ident ["<" type { "," type } ">"]. | 6392 // Parses type = [ident "."] ident ["<" type { "," type } ">"]. |
| 6334 // Returns the class object if the type can be resolved. Otherwise, either give | 6393 // Returns the class object if the type can be resolved. Otherwise, either give |
| 6335 // an error if type resolution was required, or return the unresolved name as a | 6394 // an error if type resolution was required, or return the unresolved name as a |
| 6336 // string object. | 6395 // string object. |
| 6337 RawType* Parser::ParseType(TypeResolution type_resolution) { | 6396 RawType* Parser::ParseType(TypeResolution type_resolution) { |
| 6338 if (CurrentToken() != Token::kIDENT) { | 6397 if (CurrentToken() != Token::kIDENT) { |
| 6339 ErrorMsg("type name expected"); | 6398 ErrorMsg("type name expected"); |
| 6340 } | 6399 } |
| 6341 QualIdent type_name; | 6400 QualIdent type_name; |
| 6342 intptr_t type_pos = token_index_; | 6401 const intptr_t type_pos = token_index_; |
| 6343 ParseQualIdent(&type_name); | 6402 ParseQualIdent(&type_name); |
| 6344 if (type_name.local_scope_ident) { | 6403 if (type_name.is_local_scope_ident) { |
| 6345 ErrorMsg(type_pos, "Using '%s' in this context is invalid", | 6404 ErrorMsg(type_pos, "using '%s' in this context is invalid", |
| 6346 type_name.ident->ToCString()); | 6405 type_name.ident->ToCString()); |
| 6347 } | 6406 } |
| 6348 Object& type_class = Object::Handle(); | 6407 Object& type_class = Object::Handle(); |
| 6349 if (type_resolution == kDoNotResolve) { | 6408 if (type_resolution == kDoNotResolve) { |
| 6350 String& qualifier = String::Handle(); | 6409 String& qualifier = String::Handle(); |
| 6351 if (type_name.qualifier != NULL) { | 6410 if (type_name.qualifier != NULL) { |
| 6352 qualifier ^= type_name.qualifier->raw(); | 6411 qualifier ^= type_name.qualifier->raw(); |
| 6353 } | 6412 } |
| 6354 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); | 6413 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); |
| 6355 } else { | 6414 } else { |
| 6356 TypeParameter& type_parameter = TypeParameter::Handle(); | 6415 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 6357 // Check if qualifier is a type parameter of the class we are parsing. | 6416 if (!scope_class.IsNull()) { |
| 6358 if (type_name.qualifier != NULL) { | 6417 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 6359 type_parameter = | 6418 // Check if qualifier is a type parameter in scope. |
| 6360 current_class().LookupTypeParameter(*type_name.qualifier); | 6419 if (type_name.qualifier != NULL) { |
| 6361 if (!type_parameter.IsNull()) { | 6420 type_parameter = scope_class.LookupTypeParameter(*type_name.qualifier); |
| 6362 ErrorMsg(type_pos, "Use of '%s' in this context is invalid", | 6421 if (!type_parameter.IsNull()) { |
| 6363 type_name.qualifier->ToCString()); | 6422 ErrorMsg(type_pos, "type Parameter '%s' cannot be used as qualifier", |
| 6364 } | 6423 type_name.qualifier->ToCString()); |
| 6365 } else { | |
| 6366 // Check if ident is a type parameter of the class we are parsing. | |
| 6367 type_parameter = current_class().LookupTypeParameter(*type_name.ident); | |
| 6368 if (!type_parameter.IsNull()) { | |
| 6369 CheckTypeParameterReference(type_name.ident_pos, *type_name.ident); | |
| 6370 if (CurrentToken() == Token::kLT) { | |
| 6371 // A type parameter cannot be parameterized. | |
| 6372 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", | |
| 6373 String::Handle(type_parameter.Name()).ToCString()); | |
| 6374 } | 6424 } |
| 6375 return type_parameter.raw(); | 6425 } else { |
| 6426 // Check if ident is a type parameter in scope. |
| 6427 type_parameter = scope_class.LookupTypeParameter(*type_name.ident); |
| 6428 if (!type_parameter.IsNull()) { |
| 6429 if (CurrentToken() == Token::kLT) { |
| 6430 // A type parameter cannot be parameterized. |
| 6431 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", |
| 6432 String::Handle(type_parameter.Name()).ToCString()); |
| 6433 } |
| 6434 return type_parameter.raw(); |
| 6435 } |
| 6376 } | 6436 } |
| 6377 } | 6437 } |
| 6378 // Try to resolve the type class. | 6438 // Try to resolve the type class. |
| 6379 type_class = LookupTypeClass(type_name, type_resolution); | 6439 type_class = LookupTypeClass(type_name, type_resolution); |
| 6380 } | 6440 } |
| 6381 TypeArguments& type_arguments = | 6441 TypeArguments& type_arguments = |
| 6382 TypeArguments::Handle(ParseTypeArguments(type_resolution)); | 6442 TypeArguments::Handle(ParseTypeArguments(type_resolution)); |
| 6383 Type& type = Type::Handle( | 6443 Type& type = Type::Handle( |
| 6384 Type::NewParameterizedType(type_class, type_arguments)); | 6444 Type::NewParameterizedType(type_class, type_arguments)); |
| 6385 if (type_resolution == kMustResolve) { | 6445 if (type_resolution == kMustResolve) { |
| 6386 ASSERT(type_class.IsClass()); // Must be resolved. | 6446 ASSERT(type_class.IsClass()); // Must be resolved. |
| 6387 String& errmsg = String::Handle(); | 6447 String& errmsg = String::Handle(); |
| 6388 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg); | 6448 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg); |
| 6389 if (!errmsg.IsNull()) { | 6449 if (!errmsg.IsNull()) { |
| 6390 ErrorMsg(errmsg.ToCString()); | 6450 ErrorMsg(errmsg.ToCString()); |
| 6391 } | 6451 } |
| 6392 } | 6452 } |
| 6393 return type.raw(); | 6453 return type.raw(); |
| 6394 } | 6454 } |
| 6395 | 6455 |
| 6396 | 6456 |
| 6397 void Parser::CheckConstructorCallTypeArguments( | 6457 void Parser::CheckConstructorCallTypeArguments( |
| 6398 intptr_t pos, Function& constructor, const TypeArguments& type_arguments) { | 6458 intptr_t pos, Function& constructor, const TypeArguments& type_arguments) { |
| 6399 if (!type_arguments.IsNull() && | 6459 if (!type_arguments.IsNull()) { |
| 6400 (type_arguments.Length() != | 6460 Class& signature_class = Class::Handle(); |
| 6401 Class::Handle(constructor.owner()).NumTypeArguments())) { | 6461 if (constructor.IsFactory()) { |
| 6402 ErrorMsg(pos, "Incorrect number of type arguments, expected %d got %d", | 6462 signature_class = constructor.signature_class(); |
| 6403 Class::Handle(constructor.owner()).NumTypeArguments(), | 6463 } else { |
| 6404 type_arguments.Length()); | 6464 signature_class = constructor.owner(); |
| 6465 } |
| 6466 ASSERT(!signature_class.IsNull()); |
| 6467 ASSERT(signature_class.is_finalized()); |
| 6468 if (type_arguments.Length() != signature_class.NumTypeArguments()) { |
| 6469 ErrorMsg(pos, "incorrect number of type arguments, expected %d got %d", |
| 6470 signature_class.NumTypeArguments(), |
| 6471 type_arguments.Length()); |
| 6472 } |
| 6405 } | 6473 } |
| 6406 } | 6474 } |
| 6407 | 6475 |
| 6408 | 6476 |
| 6409 // Parse "[" [ expr { "," expr } ["," ] "]". | 6477 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 6410 // Note: if the array literal is empty and the brackets have no whitespace | 6478 // Note: if the array literal is empty and the brackets have no whitespace |
| 6411 // between them, the scanner recognizes the opening and closing bracket | 6479 // between them, the scanner recognizes the opening and closing bracket |
| 6412 // as one token of type Token::kINDEX. | 6480 // as one token of type Token::kINDEX. |
| 6413 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, | 6481 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, |
| 6414 bool is_const, | 6482 bool is_const, |
| 6415 const TypeArguments& type_arguments) { | 6483 const TypeArguments& type_arguments) { |
| 6416 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 6484 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 6417 intptr_t literal_pos = token_index_; | 6485 const intptr_t literal_pos = token_index_; |
| 6418 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 6486 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 6419 ConsumeToken(); | 6487 ConsumeToken(); |
| 6420 | 6488 |
| 6421 // If no type arguments are provided, leave them as null, which is equivalent | 6489 // If no type arguments are provided, leave them as null, which is equivalent |
| 6422 // to using Array<Dynamic>. See issue 4966724. | 6490 // to using Array<Dynamic>. See issue 4966724. |
| 6423 if (!type_arguments.IsNull()) { | 6491 if (!type_arguments.IsNull()) { |
| 6424 // For now, only check the number of type arguments. See issue 4975876. | 6492 // For now, only check the number of type arguments. See issue 4975876. |
| 6425 if (type_arguments.Length() != 1) { | 6493 if (type_arguments.Length() != 1) { |
| 6426 ASSERT(type_pos >= 0); | 6494 ASSERT(type_pos >= 0); |
| 6427 ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); | 6495 ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6516 pairs->AddElement(key); | 6584 pairs->AddElement(key); |
| 6517 pairs->AddElement(value); | 6585 pairs->AddElement(value); |
| 6518 } | 6586 } |
| 6519 | 6587 |
| 6520 | 6588 |
| 6521 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 6589 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
| 6522 bool is_const, | 6590 bool is_const, |
| 6523 const TypeArguments& type_arguments) { | 6591 const TypeArguments& type_arguments) { |
| 6524 TRACE_PARSER("ParseMapLiteral"); | 6592 TRACE_PARSER("ParseMapLiteral"); |
| 6525 ASSERT(CurrentToken() == Token::kLBRACE); | 6593 ASSERT(CurrentToken() == Token::kLBRACE); |
| 6526 intptr_t literal_pos = token_index_; | 6594 const intptr_t literal_pos = token_index_; |
| 6527 ConsumeToken(); | 6595 ConsumeToken(); |
| 6528 | 6596 |
| 6529 String& map_class_name = String::Handle( | 6597 String& map_class_name = String::Handle( |
| 6530 String::NewSymbol(is_const ? kImmutableMapName : kMutableMapName)); | 6598 String::NewSymbol(is_const ? kImmutableMapName : kMutableMapName)); |
| 6531 const Class& map_class = Class::Handle(LookupImplClass(map_class_name)); | 6599 const Class& map_class = Class::Handle(LookupImplClass(map_class_name)); |
| 6532 ASSERT(!map_class.IsNull()); | 6600 ASSERT(!map_class.IsNull()); |
| 6533 | 6601 |
| 6534 TypeArguments& map_type_arguments = | 6602 TypeArguments& map_type_arguments = |
| 6535 TypeArguments::ZoneHandle(type_arguments.raw()); | 6603 TypeArguments::ZoneHandle(type_arguments.raw()); |
| 6536 // If no type arguments are provided, leave them as null, which is equivalent | 6604 // If no type arguments are provided, leave them as null, which is equivalent |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6628 } | 6696 } |
| 6629 } | 6697 } |
| 6630 | 6698 |
| 6631 | 6699 |
| 6632 AstNode* Parser::ParseCompoundLiteral() { | 6700 AstNode* Parser::ParseCompoundLiteral() { |
| 6633 bool is_const = false; | 6701 bool is_const = false; |
| 6634 if (CurrentToken() == Token::kCONST) { | 6702 if (CurrentToken() == Token::kCONST) { |
| 6635 is_const = true; | 6703 is_const = true; |
| 6636 ConsumeToken(); | 6704 ConsumeToken(); |
| 6637 } | 6705 } |
| 6638 intptr_t type_pos = token_index_; | 6706 const intptr_t type_pos = token_index_; |
| 6639 TypeArguments& type_arguments = | 6707 TypeArguments& type_arguments = |
| 6640 TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); | 6708 TypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); |
| 6641 AstNode* primary = NULL; | 6709 AstNode* primary = NULL; |
| 6642 if ((CurrentToken() == Token::kLBRACK) || | 6710 if ((CurrentToken() == Token::kLBRACK) || |
| 6643 (CurrentToken() == Token::kINDEX)) { | 6711 (CurrentToken() == Token::kINDEX)) { |
| 6644 primary = ParseArrayLiteral(type_pos, is_const, type_arguments); | 6712 primary = ParseArrayLiteral(type_pos, is_const, type_arguments); |
| 6645 } else if (CurrentToken() == Token::kLBRACE) { | 6713 } else if (CurrentToken() == Token::kLBRACE) { |
| 6646 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 6714 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 6647 } else { | 6715 } else { |
| 6648 ErrorMsg("Unexpected token %s", Token::Str(CurrentToken())); | 6716 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); |
| 6649 } | 6717 } |
| 6650 return primary; | 6718 return primary; |
| 6651 } | 6719 } |
| 6652 | 6720 |
| 6653 | 6721 |
| 6654 static const String& BuildConstructorName(const String& type_class_name, | 6722 static const String& BuildConstructorName(const String& type_class_name, |
| 6655 const String* named_constructor) { | 6723 const String* named_constructor) { |
| 6656 // By convention, the static function implementing a named constructor 'C' | 6724 // By convention, the static function implementing a named constructor 'C' |
| 6657 // for class 'A' is labeled 'A.C', and the static function implementing the | 6725 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 6658 // unnamed constructor for class 'A' is labeled 'A.'. | 6726 // unnamed constructor for class 'A' is labeled 'A.'. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6681 // constructor. For that reason, we cannot unconditionally call | 6749 // constructor. For that reason, we cannot unconditionally call |
| 6682 // ParseType(kMustResolve) after we see an identifier, because the named | 6750 // ParseType(kMustResolve) after we see an identifier, because the named |
| 6683 // constructor would be misinterpreted as a qualified type name. | 6751 // constructor would be misinterpreted as a qualified type name. |
| 6684 // TODO(regis): Revisit once we correctly support qualified identifiers. | 6752 // TODO(regis): Revisit once we correctly support qualified identifiers. |
| 6685 // For now, we inline a customized version of ParseType(kMustResolve). | 6753 // For now, we inline a customized version of ParseType(kMustResolve). |
| 6686 Type& type = Type::Handle(); | 6754 Type& type = Type::Handle(); |
| 6687 Class& type_class = Class::ZoneHandle(); | 6755 Class& type_class = Class::ZoneHandle(); |
| 6688 String& type_class_name = String::Handle(); | 6756 String& type_class_name = String::Handle(); |
| 6689 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); | 6757 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); |
| 6690 String* named_constructor = NULL; | 6758 String* named_constructor = NULL; |
| 6691 intptr_t type_pos = token_index_; | 6759 const intptr_t type_pos = token_index_; |
| 6692 QualIdent type_name; | 6760 QualIdent type_name; |
| 6693 ParseQualIdent(&type_name); | 6761 ParseQualIdent(&type_name); |
| 6694 if (type_name.local_scope_ident) { | 6762 if (type_name.is_local_scope_ident) { |
| 6695 ErrorMsg(type_pos, "Using '%s' in this context is invalid", | 6763 ErrorMsg(type_pos, "using '%s' in this context is invalid", |
| 6696 type_name.ident->ToCString()); | 6764 type_name.ident->ToCString()); |
| 6697 } | 6765 } |
| 6698 if (CurrentToken() == Token::kPERIOD) { | 6766 if (CurrentToken() == Token::kPERIOD) { |
| 6699 ConsumeToken(); | 6767 ConsumeToken(); |
| 6700 named_constructor = ExpectIdentifier("identifier expected after '.'"); | 6768 named_constructor = ExpectIdentifier("identifier expected after '.'"); |
| 6701 } | 6769 } |
| 6702 TypeParameter& type_parameter = TypeParameter::Handle(); | 6770 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 6703 if (type_name.lib_prefix != NULL) { | 6771 if (!scope_class.IsNull()) { |
| 6704 // TODO(regis): Ascertain that this check for shadowing is valid | 6772 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 6705 // See bug (490270). | 6773 if (type_name.lib_prefix != NULL) { |
| 6706 // Check if qualifier is a type parameter of the class we are parsing. | 6774 // Check if qualifier is a type parameter in scope. |
| 6707 type_parameter ^= current_class().LookupTypeParameter(*type_name.qualifier); | 6775 type_parameter ^= scope_class.LookupTypeParameter(*type_name.qualifier); |
| 6776 if (!type_parameter.IsNull()) { |
| 6777 ErrorMsg(type_pos, "type parameter '%s' cannot be used as qualifier", |
| 6778 String::Handle(type_parameter.Name()).ToCString()); |
| 6779 } |
| 6780 } |
| 6781 // Check if ident is a type parameter in scope. |
| 6782 type_parameter = scope_class.LookupTypeParameter(*type_name.ident); |
| 6708 if (!type_parameter.IsNull()) { | 6783 if (!type_parameter.IsNull()) { |
| 6709 CheckTypeParameterReference(type_pos, *type_name.qualifier); | |
| 6710 ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated", | 6784 ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated", |
| 6711 String::Handle(type_parameter.Name()).ToCString()); | 6785 String::Handle(type_parameter.Name()).ToCString()); |
| 6712 } | 6786 } |
| 6713 } | 6787 } |
| 6714 // Check if ident is a type parameter of the class we are parsing. | |
| 6715 type_parameter = current_class().LookupTypeParameter(*type_name.ident); | |
| 6716 if (!type_parameter.IsNull()) { | |
| 6717 CheckTypeParameterReference(type_name.ident_pos, *type_name.ident); | |
| 6718 ErrorMsg(type_pos, "type parameter '%s' cannot be instantiated", | |
| 6719 String::Handle(type_parameter.Name()).ToCString()); | |
| 6720 } | |
| 6721 type_class ^= LookupTypeClass(type_name, kMustResolve); | 6788 type_class ^= LookupTypeClass(type_name, kMustResolve); |
| 6722 type_class_name = type_class.Name(); | 6789 type_class_name = type_class.Name(); |
| 6723 // Type arguments are not allowed after the optional constructor name. | 6790 // Type arguments are not allowed after the optional constructor name. |
| 6724 if (named_constructor == NULL) { | 6791 if (named_constructor == NULL) { |
| 6725 type_arguments = ParseTypeArguments(kMustResolve); | 6792 type_arguments = ParseTypeArguments(kMustResolve); |
| 6726 type = Type::NewParameterizedType(type_class, type_arguments); | 6793 type = Type::NewParameterizedType(type_class, type_arguments); |
| 6727 String& errmsg = String::Handle(); | 6794 String& errmsg = String::Handle(); |
| 6728 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg); | 6795 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg); |
| 6729 if (!errmsg.IsNull()) { | 6796 if (!errmsg.IsNull()) { |
| 6730 ErrorMsg(errmsg.ToCString()); | 6797 ErrorMsg(errmsg.ToCString()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6762 ErrorMsg(new_pos, "interface '%s' has no constructor named '%s'", | 6829 ErrorMsg(new_pos, "interface '%s' has no constructor named '%s'", |
| 6763 type_class_name.ToCString(), | 6830 type_class_name.ToCString(), |
| 6764 external_constructor_name.ToCString()); | 6831 external_constructor_name.ToCString()); |
| 6765 } | 6832 } |
| 6766 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { | 6833 if (!constructor.AreValidArguments(arguments_length, arguments->names())) { |
| 6767 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " | 6834 ErrorMsg(new_pos, "invalid arguments passed to constructor '%s' " |
| 6768 "for interface '%s'", | 6835 "for interface '%s'", |
| 6769 external_constructor_name.ToCString(), | 6836 external_constructor_name.ToCString(), |
| 6770 type_class_name.ToCString()); | 6837 type_class_name.ToCString()); |
| 6771 } | 6838 } |
| 6772 | 6839 if (!type_class.HasFactoryClass()) { |
| 6773 // TODO(srdjan): Evaluate if the mapping should occur during code | |
| 6774 // generation or here in the parser. | |
| 6775 const Type& factory_type = Type::Handle(type_class.factory_type()); | |
| 6776 if (factory_type.IsNull()) { | |
| 6777 ErrorMsg("cannot allocate interface '%s' without factory class", | 6840 ErrorMsg("cannot allocate interface '%s' without factory class", |
| 6778 type_class_name.ToCString()); | 6841 type_class_name.ToCString()); |
| 6779 } | 6842 } |
| 6780 if (!factory_type.HasResolvedTypeClass()) { | 6843 if (!type_class.HasResolvedFactoryClass()) { |
| 6781 // This error can occur only with bootstrap classes. | 6844 // This error can occur only with bootstrap classes. |
| 6782 const UnresolvedClass& unresolved = | 6845 const UnresolvedClass& unresolved = |
| 6783 UnresolvedClass::Handle(factory_type.unresolved_class()); | 6846 UnresolvedClass::Handle(type_class.UnresolvedFactoryClass()); |
| 6784 const String& missing_class_name = String::Handle(unresolved.ident()); | 6847 const String& missing_class_name = String::Handle(unresolved.ident()); |
| 6785 ErrorMsg("Unresolved factory class '%s'", missing_class_name.ToCString()); | 6848 ErrorMsg("unresolved factory class '%s'", missing_class_name.ToCString()); |
| 6786 } | 6849 } |
| 6787 | |
| 6788 // Only change the class of the constructor to the factory class if the | 6850 // Only change the class of the constructor to the factory class if the |
| 6789 // factory class implements the interface 'type'. | 6851 // factory class implements the interface 'type'. |
| 6790 Class& factory_type_class = Class::Handle(factory_type.type_class()); | 6852 const Class& factory_class = Class::Handle(type_class.FactoryClass()); |
| 6791 // TODO(regis): Verify in the guide/spec that a factory class must have | 6853 if (factory_class.IsSubtypeOf(TypeArguments::Handle(), |
| 6792 // identical type parameters as the interface. | 6854 type_class, |
| 6793 // TODO(regis): Do we check that in the parser? | 6855 TypeArguments::Handle())) { |
| 6794 // Assuming that it has been checked, it is sufficient to test if the | 6856 // Class finalization verifies that the factory class has identical type |
| 6795 // raw factory type implements the raw interface type. | 6857 // parameters as the interface. |
| 6796 if (factory_type_class.IsSubtypeOf(TypeArguments::Handle(), | 6858 type_class_name = factory_class.Name(); |
| 6797 type_class, | |
| 6798 TypeArguments::Handle())) { | |
| 6799 type_class_name = factory_type_class.Name(); | |
| 6800 } | 6859 } |
| 6801 // Always change the result type of the constructor to the factory type. | 6860 // Always change the result type of the constructor to the factory type. |
| 6802 type_class = factory_type_class.raw(); | 6861 type_class = factory_class.raw(); |
| 6803 ASSERT(!type_class.is_interface()); | 6862 ASSERT(!type_class.is_interface()); |
| 6804 } | 6863 } |
| 6805 | 6864 |
| 6806 // Make sure that an appropriate constructor exists. | 6865 // Make sure that an appropriate constructor exists. |
| 6807 const String& constructor_name = | 6866 const String& constructor_name = |
| 6808 BuildConstructorName(type_class_name, named_constructor); | 6867 BuildConstructorName(type_class_name, named_constructor); |
| 6809 const String& external_constructor_name = | 6868 const String& external_constructor_name = |
| 6810 (named_constructor ? constructor_name : type_class_name); | 6869 (named_constructor ? constructor_name : type_class_name); |
| 6811 Function& constructor = Function::ZoneHandle( | 6870 Function& constructor = Function::ZoneHandle( |
| 6812 type_class.LookupConstructor(constructor_name)); | 6871 type_class.LookupConstructor(constructor_name)); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6861 | 6920 |
| 6862 // A string literal consists of the concatenation of the next n tokens | 6921 // A string literal consists of the concatenation of the next n tokens |
| 6863 // that satisfy the EBNF grammar: | 6922 // that satisfy the EBNF grammar: |
| 6864 // literal = kSTRING {{ interpol }+ kSTRING } | 6923 // literal = kSTRING {{ interpol }+ kSTRING } |
| 6865 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 6924 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 6866 // In other words, the scanner breaks down interpolated strings so that | 6925 // In other words, the scanner breaks down interpolated strings so that |
| 6867 // a string literal always begins and ends with a kSTRING token, and | 6926 // a string literal always begins and ends with a kSTRING token, and |
| 6868 // there are never two kSTRING tokens next to each other. | 6927 // there are never two kSTRING tokens next to each other. |
| 6869 AstNode* Parser::ParseStringLiteral() { | 6928 AstNode* Parser::ParseStringLiteral() { |
| 6870 AstNode* primary = NULL; | 6929 AstNode* primary = NULL; |
| 6871 intptr_t literal_start = token_index_; | 6930 const intptr_t literal_start = token_index_; |
| 6872 if ((CurrentToken() == Token::kSTRING) && | 6931 if ((CurrentToken() == Token::kSTRING) && |
| 6873 (LookaheadToken(1) != Token::kINTERPOL_VAR) && | 6932 (LookaheadToken(1) != Token::kINTERPOL_VAR) && |
| 6874 (LookaheadToken(1) != Token::kINTERPOL_START)) { | 6933 (LookaheadToken(1) != Token::kINTERPOL_START)) { |
| 6875 // Common case: no interpolation. | 6934 // Common case: no interpolation. |
| 6876 primary = new LiteralNode(literal_start, *CurrentLiteral()); | 6935 primary = new LiteralNode(literal_start, *CurrentLiteral()); |
| 6877 ConsumeToken(); | 6936 ConsumeToken(); |
| 6878 return primary; | 6937 return primary; |
| 6879 } | 6938 } |
| 6880 // String interpolation needed. | 6939 // String interpolation needed. |
| 6881 ArrayNode* values = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 6940 ArrayNode* values = new ArrayNode(token_index_, TypeArguments::ZoneHandle()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6920 AstNode* primary = NULL; | 6979 AstNode* primary = NULL; |
| 6921 if (IsFunctionLiteral()) { | 6980 if (IsFunctionLiteral()) { |
| 6922 // The name of a literal function is visible from inside the function, but | 6981 // The name of a literal function is visible from inside the function, but |
| 6923 // must not collide with names in the scope declaring the literal. | 6982 // must not collide with names in the scope declaring the literal. |
| 6924 OpenBlock(); | 6983 OpenBlock(); |
| 6925 primary = ParseFunctionStatement(true); | 6984 primary = ParseFunctionStatement(true); |
| 6926 CloseBlock(); | 6985 CloseBlock(); |
| 6927 } else if (CurrentToken() == Token::kIDENT) { | 6986 } else if (CurrentToken() == Token::kIDENT) { |
| 6928 QualIdent qual_ident; | 6987 QualIdent qual_ident; |
| 6929 ParseQualIdent(&qual_ident); | 6988 ParseQualIdent(&qual_ident); |
| 6930 if (qual_ident.local_scope_ident) { | 6989 if (qual_ident.is_local_scope_ident) { |
| 6931 ResolveIdentInLocalScope(qual_ident.ident_pos, | 6990 ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 6932 *qual_ident.ident, | 6991 *qual_ident.ident, |
| 6933 &primary); | 6992 &primary); |
| 6934 } else { | 6993 } else { |
| 6935 if (qual_ident.qualifier == NULL) { | 6994 if (qual_ident.qualifier == NULL) { |
| 6936 // This is an unqualified identifier so resolve the identifier | 6995 // This is an unqualified identifier so resolve the identifier |
| 6937 // locally in the main app library and all libraries imported by it. | 6996 // locally in the main app library and all libraries imported by it. |
| 6938 primary = ResolveIdentInLibraryScope(library_, | 6997 primary = ResolveIdentInLibraryScope(library_, |
| 6939 qual_ident, | 6998 qual_ident, |
| 6940 kResolveIncludingImports); | 6999 kResolveIncludingImports); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7021 const String& ident = *ExpectIdentifier("identifier expected"); | 7080 const String& ident = *ExpectIdentifier("identifier expected"); |
| 7022 if (CurrentToken() == Token::kLPAREN) { | 7081 if (CurrentToken() == Token::kLPAREN) { |
| 7023 primary = ParseSuperCall(ident); | 7082 primary = ParseSuperCall(ident); |
| 7024 } else { | 7083 } else { |
| 7025 primary = ParseSuperFieldAccess(ident); | 7084 primary = ParseSuperFieldAccess(ident); |
| 7026 } | 7085 } |
| 7027 } else if ((CurrentToken() == Token::kLBRACK) || | 7086 } else if ((CurrentToken() == Token::kLBRACK) || |
| 7028 Token::CanBeOverloaded(CurrentToken())) { | 7087 Token::CanBeOverloaded(CurrentToken())) { |
| 7029 primary = ParseSuperOperator(); | 7088 primary = ParseSuperOperator(); |
| 7030 } else { | 7089 } else { |
| 7031 ErrorMsg("Illegal super call"); | 7090 ErrorMsg("illegal super call"); |
| 7032 } | 7091 } |
| 7033 } else { | 7092 } else { |
| 7034 UnexpectedToken(); | 7093 UnexpectedToken(); |
| 7035 } | 7094 } |
| 7036 return primary; | 7095 return primary; |
| 7037 } | 7096 } |
| 7038 | 7097 |
| 7039 | 7098 |
| 7040 // Evaluate expression in expr and return the value. The expression must | 7099 // Evaluate expression in expr and return the value. The expression must |
| 7041 // be a compile time constant. | 7100 // be a compile time constant. |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7289 } | 7348 } |
| 7290 | 7349 |
| 7291 | 7350 |
| 7292 void Parser::SkipNestedExpr() { | 7351 void Parser::SkipNestedExpr() { |
| 7293 const bool saved_mode = SetAllowFunctionLiterals(true); | 7352 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7294 SkipExpr(); | 7353 SkipExpr(); |
| 7295 SetAllowFunctionLiterals(saved_mode); | 7354 SetAllowFunctionLiterals(saved_mode); |
| 7296 } | 7355 } |
| 7297 | 7356 |
| 7298 } // namespace dart | 7357 } // namespace dart |
| OLD | NEW |