| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 | 527 |
| 528 | 528 |
| 529 class ClassDesc : public ValueObject { | 529 class ClassDesc : public ValueObject { |
| 530 public: | 530 public: |
| 531 ClassDesc(const Class& cls, | 531 ClassDesc(const Class& cls, |
| 532 const String& cls_name, | 532 const String& cls_name, |
| 533 bool is_interface, | 533 bool is_interface, |
| 534 intptr_t token_pos) | 534 intptr_t token_pos) |
| 535 : clazz_(cls), | 535 : clazz_(cls), |
| 536 class_name_(cls_name), | 536 class_name_(cls_name), |
| 537 is_interface_(is_interface), | |
| 538 token_pos_(token_pos), | 537 token_pos_(token_pos), |
| 539 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 538 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 540 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { | 539 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { |
| 541 } | 540 } |
| 542 | 541 |
| 543 // Parameter 'name' is the unmangled name, i.e. without the setter | 542 // Parameter 'name' is the unmangled name, i.e. without the setter |
| 544 // name mangling. | 543 // name mangling. |
| 545 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { | 544 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { |
| 546 // First check if a function or field of same name exists. | 545 // First check if a function or field of same name exists. |
| 547 if ((kind != RawFunction::kSetterFunction) && FunctionExists(name)) { | 546 if ((kind != RawFunction::kSetterFunction) && FunctionExists(name)) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 } | 617 } |
| 619 | 618 |
| 620 RawClass* clazz() const { | 619 RawClass* clazz() const { |
| 621 return clazz_.raw(); | 620 return clazz_.raw(); |
| 622 } | 621 } |
| 623 | 622 |
| 624 const String& class_name() const { | 623 const String& class_name() const { |
| 625 return class_name_; | 624 return class_name_; |
| 626 } | 625 } |
| 627 | 626 |
| 628 bool is_interface() const { | |
| 629 return is_interface_; | |
| 630 } | |
| 631 | |
| 632 bool has_constructor() const { | 627 bool has_constructor() const { |
| 633 Function& func = Function::Handle(); | 628 Function& func = Function::Handle(); |
| 634 for (int i = 0; i < functions_.Length(); i++) { | 629 for (int i = 0; i < functions_.Length(); i++) { |
| 635 func ^= functions_.At(i); | 630 func ^= functions_.At(i); |
| 636 if (func.kind() == RawFunction::kConstructor) { | 631 if (func.kind() == RawFunction::kConstructor) { |
| 637 return true; | 632 return true; |
| 638 } | 633 } |
| 639 } | 634 } |
| 640 return false; | 635 return false; |
| 641 } | 636 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 } | 686 } |
| 692 return NULL; | 687 return NULL; |
| 693 } | 688 } |
| 694 | 689 |
| 695 bool FunctionExists(const String& name) const { | 690 bool FunctionExists(const String& name) const { |
| 696 return LookupFunction(name) != NULL; | 691 return LookupFunction(name) != NULL; |
| 697 } | 692 } |
| 698 | 693 |
| 699 const Class& clazz_; | 694 const Class& clazz_; |
| 700 const String& class_name_; | 695 const String& class_name_; |
| 701 const bool is_interface_; | |
| 702 intptr_t token_pos_; // Token index of "class" keyword. | 696 intptr_t token_pos_; // Token index of "class" keyword. |
| 703 GrowableObjectArray& functions_; | 697 GrowableObjectArray& functions_; |
| 704 GrowableObjectArray& fields_; | 698 GrowableObjectArray& fields_; |
| 705 GrowableArray<MemberDesc> members_; | 699 GrowableArray<MemberDesc> members_; |
| 706 }; | 700 }; |
| 707 | 701 |
| 708 | 702 |
| 709 struct TopLevel { | 703 struct TopLevel { |
| 710 TopLevel() : | 704 TopLevel() : |
| 711 fields(GrowableObjectArray::Handle(GrowableObjectArray::New())), | 705 fields(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1279 if (CurrentToken() != Token::kSTRING) { | 1273 if (CurrentToken() != Token::kSTRING) { |
| 1280 ErrorMsg("string literal expected"); | 1274 ErrorMsg("string literal expected"); |
| 1281 } | 1275 } |
| 1282 String& native_name = *CurrentLiteral(); | 1276 String& native_name = *CurrentLiteral(); |
| 1283 ConsumeToken(); | 1277 ConsumeToken(); |
| 1284 ExpectSemicolon(); | 1278 ExpectSemicolon(); |
| 1285 return native_name; | 1279 return native_name; |
| 1286 } | 1280 } |
| 1287 | 1281 |
| 1288 | 1282 |
| 1289 void Parser::CheckFunctionIsCallable(intptr_t token_pos, | |
| 1290 const Function& function) { | |
| 1291 if (Class::Handle(function.Owner()).is_interface()) { | |
| 1292 ErrorMsg(token_pos, "cannot call function of interface '%s'", | |
| 1293 function.ToFullyQualifiedCString()); | |
| 1294 } | |
| 1295 } | |
| 1296 | |
| 1297 | |
| 1298 // Resolve and return the dynamic function of the given name in the superclass. | 1283 // Resolve and return the dynamic function of the given name in the superclass. |
| 1299 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1284 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1300 // the same name. If it is still not found, return noSuchMethod and | 1285 // the same name. If it is still not found, return noSuchMethod and |
| 1301 // set is_no_such_method to true.. | 1286 // set is_no_such_method to true.. |
| 1302 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1287 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1303 const String& name, | 1288 const String& name, |
| 1304 bool resolve_getter, | 1289 bool resolve_getter, |
| 1305 bool* is_no_such_method) { | 1290 bool* is_no_such_method) { |
| 1306 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1291 const Class& super_class = Class::Handle(current_class().SuperClass()); |
| 1307 if (super_class.IsNull()) { | 1292 if (super_class.IsNull()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1318 } | 1303 } |
| 1319 if (super_func.IsNull()) { | 1304 if (super_func.IsNull()) { |
| 1320 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); | 1305 const String& no_such_method_name = String::Handle(Symbols::NoSuchMethod()); |
| 1321 super_func = | 1306 super_func = |
| 1322 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); | 1307 Resolver::ResolveDynamicAnyArgs(super_class, no_such_method_name); |
| 1323 ASSERT(!super_func.IsNull()); | 1308 ASSERT(!super_func.IsNull()); |
| 1324 *is_no_such_method = true; | 1309 *is_no_such_method = true; |
| 1325 } else { | 1310 } else { |
| 1326 *is_no_such_method = false; | 1311 *is_no_such_method = false; |
| 1327 } | 1312 } |
| 1328 CheckFunctionIsCallable(token_pos, super_func); | |
| 1329 return super_func.raw(); | 1313 return super_func.raw(); |
| 1330 } | 1314 } |
| 1331 | 1315 |
| 1332 | 1316 |
| 1333 // Lookup class in the core lib which also contains various VM | 1317 // Lookup class in the core lib which also contains various VM |
| 1334 // helper methods and classes. Allow look up of private classes. | 1318 // helper methods and classes. Allow look up of private classes. |
| 1335 static RawClass* LookupCoreClass(const String& class_name) { | 1319 static RawClass* LookupCoreClass(const String& class_name) { |
| 1336 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1320 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1337 String& name = String::Handle(class_name.raw()); | 1321 String& name = String::Handle(class_name.raw()); |
| 1338 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 1322 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1451 const bool kResolveGetter = false; | 1435 const bool kResolveGetter = false; |
| 1452 bool is_no_such_method = false; | 1436 bool is_no_such_method = false; |
| 1453 const Function& super_operator = Function::ZoneHandle( | 1437 const Function& super_operator = Function::ZoneHandle( |
| 1454 GetSuperFunction(super_pos, | 1438 GetSuperFunction(super_pos, |
| 1455 operator_function_name, | 1439 operator_function_name, |
| 1456 kResolveGetter, | 1440 kResolveGetter, |
| 1457 &is_no_such_method)); | 1441 &is_no_such_method)); |
| 1458 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 1442 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
| 1459 AstNode* receiver = LoadReceiver(super_pos); | 1443 AstNode* receiver = LoadReceiver(super_pos); |
| 1460 op_arguments->Add(receiver); | 1444 op_arguments->Add(receiver); |
| 1461 CheckFunctionIsCallable(super_pos, super_operator); | |
| 1462 if (is_no_such_method) { | 1445 if (is_no_such_method) { |
| 1463 op_arguments = BuildNoSuchMethodArguments( | 1446 op_arguments = BuildNoSuchMethodArguments( |
| 1464 super_pos, operator_function_name, *op_arguments); | 1447 super_pos, operator_function_name, *op_arguments); |
| 1465 } | 1448 } |
| 1466 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 1449 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
| 1467 } else { | 1450 } else { |
| 1468 ErrorMsg(super_pos, "illegal super operator call"); | 1451 ErrorMsg(super_pos, "illegal super operator call"); |
| 1469 } | 1452 } |
| 1470 return super_op; | 1453 return super_op; |
| 1471 } | 1454 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 &is_no_such_method)); | 1491 &is_no_such_method)); |
| 1509 | 1492 |
| 1510 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); | 1493 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); |
| 1511 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); | 1494 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); |
| 1512 | 1495 |
| 1513 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); | 1496 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); |
| 1514 AstNode* receiver = LoadReceiver(operator_pos); | 1497 AstNode* receiver = LoadReceiver(operator_pos); |
| 1515 op_arguments->Add(receiver); | 1498 op_arguments->Add(receiver); |
| 1516 op_arguments->Add(other_operand); | 1499 op_arguments->Add(other_operand); |
| 1517 | 1500 |
| 1518 CheckFunctionIsCallable(operator_pos, super_operator); | |
| 1519 if (is_no_such_method) { | 1501 if (is_no_such_method) { |
| 1520 op_arguments = BuildNoSuchMethodArguments( | 1502 op_arguments = BuildNoSuchMethodArguments( |
| 1521 operator_pos, operator_function_name, *op_arguments); | 1503 operator_pos, operator_function_name, *op_arguments); |
| 1522 } | 1504 } |
| 1523 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 1505 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| 1524 if (negate_result) { | 1506 if (negate_result) { |
| 1525 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 1507 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
| 1526 } | 1508 } |
| 1527 } | 1509 } |
| 1528 return super_op; | 1510 return super_op; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 } | 1609 } |
| 1628 String& error_message = String::Handle(); | 1610 String& error_message = String::Handle(); |
| 1629 if (!super_ctor.AreValidArguments(arguments->length(), | 1611 if (!super_ctor.AreValidArguments(arguments->length(), |
| 1630 arguments->names(), | 1612 arguments->names(), |
| 1631 &error_message)) { | 1613 &error_message)) { |
| 1632 ErrorMsg(supercall_pos, | 1614 ErrorMsg(supercall_pos, |
| 1633 "invalid arguments passed to super constructor '%s()': %s", | 1615 "invalid arguments passed to super constructor '%s()': %s", |
| 1634 String::Handle(super_class.Name()).ToCString(), | 1616 String::Handle(super_class.Name()).ToCString(), |
| 1635 error_message.ToCString()); | 1617 error_message.ToCString()); |
| 1636 } | 1618 } |
| 1637 CheckFunctionIsCallable(supercall_pos, super_ctor); | |
| 1638 current_block_->statements->Add( | 1619 current_block_->statements->Add( |
| 1639 new StaticCallNode(supercall_pos, super_ctor, arguments)); | 1620 new StaticCallNode(supercall_pos, super_ctor, arguments)); |
| 1640 } | 1621 } |
| 1641 | 1622 |
| 1642 | 1623 |
| 1643 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 1624 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 1644 LocalVariable* receiver) { | 1625 LocalVariable* receiver) { |
| 1645 TRACE_PARSER("ParseSuperInitializer"); | 1626 TRACE_PARSER("ParseSuperInitializer"); |
| 1646 ASSERT(CurrentToken() == Token::kSUPER); | 1627 ASSERT(CurrentToken() == Token::kSUPER); |
| 1647 const intptr_t supercall_pos = TokenPos(); | 1628 const intptr_t supercall_pos = TokenPos(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 } | 1668 } |
| 1688 String& error_message = String::Handle(); | 1669 String& error_message = String::Handle(); |
| 1689 if (!super_ctor.AreValidArguments(arguments->length(), | 1670 if (!super_ctor.AreValidArguments(arguments->length(), |
| 1690 arguments->names(), | 1671 arguments->names(), |
| 1691 &error_message)) { | 1672 &error_message)) { |
| 1692 ErrorMsg(supercall_pos, | 1673 ErrorMsg(supercall_pos, |
| 1693 "invalid arguments passed to super class constructor '%s': %s", | 1674 "invalid arguments passed to super class constructor '%s': %s", |
| 1694 ctor_name.ToCString(), | 1675 ctor_name.ToCString(), |
| 1695 error_message.ToCString()); | 1676 error_message.ToCString()); |
| 1696 } | 1677 } |
| 1697 CheckFunctionIsCallable(supercall_pos, super_ctor); | |
| 1698 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 1678 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 1699 } | 1679 } |
| 1700 | 1680 |
| 1701 | 1681 |
| 1702 AstNode* Parser::ParseInitializer(const Class& cls, | 1682 AstNode* Parser::ParseInitializer(const Class& cls, |
| 1703 LocalVariable* receiver, | 1683 LocalVariable* receiver, |
| 1704 GrowableArray<Field*>* initialized_fields) { | 1684 GrowableArray<Field*>* initialized_fields) { |
| 1705 TRACE_PARSER("ParseInitializer"); | 1685 TRACE_PARSER("ParseInitializer"); |
| 1706 const intptr_t field_pos = TokenPos(); | 1686 const intptr_t field_pos = TokenPos(); |
| 1707 if (CurrentToken() == Token::kTHIS) { | 1687 if (CurrentToken() == Token::kTHIS) { |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 } | 1881 } |
| 1902 String& error_message = String::Handle(); | 1882 String& error_message = String::Handle(); |
| 1903 if (!redirect_ctor.AreValidArguments(arguments->length(), | 1883 if (!redirect_ctor.AreValidArguments(arguments->length(), |
| 1904 arguments->names(), | 1884 arguments->names(), |
| 1905 &error_message)) { | 1885 &error_message)) { |
| 1906 ErrorMsg(call_pos, | 1886 ErrorMsg(call_pos, |
| 1907 "invalid arguments passed to constructor '%s': %s", | 1887 "invalid arguments passed to constructor '%s': %s", |
| 1908 ctor_name.ToCString(), | 1888 ctor_name.ToCString(), |
| 1909 error_message.ToCString()); | 1889 error_message.ToCString()); |
| 1910 } | 1890 } |
| 1911 CheckFunctionIsCallable(call_pos, redirect_ctor); | |
| 1912 current_block_->statements->Add( | 1891 current_block_->statements->Add( |
| 1913 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 1892 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 1914 } | 1893 } |
| 1915 | 1894 |
| 1916 | 1895 |
| 1917 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 1896 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 1918 ASSERT(func.IsConstructor()); | 1897 ASSERT(func.IsConstructor()); |
| 1919 const intptr_t ctor_pos = TokenPos(); | 1898 const intptr_t ctor_pos = TokenPos(); |
| 1920 OpenFunctionBlock(func); | 1899 OpenFunctionBlock(func); |
| 1921 const Class& cls = Class::Handle(func.Owner()); | 1900 const Class& cls = Class::Handle(func.Owner()); |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2440 if (method->has_const && !method->IsFactoryOrConstructor()) { | 2419 if (method->has_const && !method->IsFactoryOrConstructor()) { |
| 2441 ErrorMsg(method->name_pos, "'const' not allowed for methods"); | 2420 ErrorMsg(method->name_pos, "'const' not allowed for methods"); |
| 2442 } | 2421 } |
| 2443 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 2422 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
| 2444 ErrorMsg(method->name_pos, "constructor cannot be abstract"); | 2423 ErrorMsg(method->name_pos, "constructor cannot be abstract"); |
| 2445 } | 2424 } |
| 2446 if (method->has_const && method->IsConstructor()) { | 2425 if (method->has_const && method->IsConstructor()) { |
| 2447 Class& cls = Class::Handle(library_.LookupClass(members->class_name())); | 2426 Class& cls = Class::Handle(library_.LookupClass(members->class_name())); |
| 2448 cls.set_is_const(); | 2427 cls.set_is_const(); |
| 2449 } | 2428 } |
| 2450 if (method->has_abstract && members->is_interface()) { | |
| 2451 ErrorMsg(method->name_pos, | |
| 2452 "'abstract' method only allowed in class definition"); | |
| 2453 } | |
| 2454 if (method->has_external && members->is_interface()) { | |
| 2455 ErrorMsg(method->name_pos, | |
| 2456 "'external' method only allowed in class definition"); | |
| 2457 } | |
| 2458 | 2429 |
| 2459 // Parse the formal parameters. | 2430 // Parse the formal parameters. |
| 2460 const bool are_implicitly_final = method->has_const; | 2431 const bool are_implicitly_final = method->has_const; |
| 2461 const bool allow_explicit_default_values = true; | 2432 const bool allow_explicit_default_values = true; |
| 2462 const intptr_t formal_param_pos = TokenPos(); | 2433 const intptr_t formal_param_pos = TokenPos(); |
| 2463 method->params.Clear(); | 2434 method->params.Clear(); |
| 2464 // Static functions do not have a receiver. | 2435 // Static functions do not have a receiver. |
| 2465 // The first parameter of a factory is the AbstractTypeArguments vector of | 2436 // The first parameter of a factory is the AbstractTypeArguments vector of |
| 2466 // the type of the instance to be allocated. | 2437 // the type of the instance to be allocated. |
| 2467 if (!method->has_static || method->IsConstructor()) { | 2438 if (!method->has_static || method->IsConstructor()) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2598 "abstract method '%s' may not have a function body", | 2569 "abstract method '%s' may not have a function body", |
| 2599 method->name->ToCString()); | 2570 method->name->ToCString()); |
| 2600 } else if (method->has_external) { | 2571 } else if (method->has_external) { |
| 2601 ErrorMsg(method->name_pos, | 2572 ErrorMsg(method->name_pos, |
| 2602 "external method '%s' may not have a function body", | 2573 "external method '%s' may not have a function body", |
| 2603 method->name->ToCString()); | 2574 method->name->ToCString()); |
| 2604 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 2575 } else if (method->IsFactoryOrConstructor() && method->has_const) { |
| 2605 ErrorMsg(method->name_pos, | 2576 ErrorMsg(method->name_pos, |
| 2606 "const constructor or factory '%s' may not have a function body", | 2577 "const constructor or factory '%s' may not have a function body", |
| 2607 method->name->ToCString()); | 2578 method->name->ToCString()); |
| 2608 } else if (members->is_interface()) { | |
| 2609 ErrorMsg(method->name_pos, | |
| 2610 "function body not allowed in interface declaration"); | |
| 2611 } | 2579 } |
| 2612 if (method->redirect_name != NULL) { | 2580 if (method->redirect_name != NULL) { |
| 2613 ErrorMsg(method->name_pos, | 2581 ErrorMsg(method->name_pos, |
| 2614 "Constructor with redirection may not have a function body"); | 2582 "Constructor with redirection may not have a function body"); |
| 2615 } | 2583 } |
| 2616 if (CurrentToken() == Token::kLBRACE) { | 2584 if (CurrentToken() == Token::kLBRACE) { |
| 2617 SkipBlock(); | 2585 SkipBlock(); |
| 2618 } else { | 2586 } else { |
| 2619 ConsumeToken(); | 2587 ConsumeToken(); |
| 2620 SkipExpr(); | 2588 SkipExpr(); |
| 2621 ExpectSemicolon(); | 2589 ExpectSemicolon(); |
| 2622 } | 2590 } |
| 2623 method_end_pos = TokenPos(); | 2591 method_end_pos = TokenPos(); |
| 2624 } else if (IsLiteral("native")) { | 2592 } else if (IsLiteral("native")) { |
| 2625 if (method->has_abstract) { | 2593 if (method->has_abstract) { |
| 2626 ErrorMsg(method->name_pos, | 2594 ErrorMsg(method->name_pos, |
| 2627 "abstract method '%s' may not have a function body", | 2595 "abstract method '%s' may not have a function body", |
| 2628 method->name->ToCString()); | 2596 method->name->ToCString()); |
| 2629 } else if (members->is_interface()) { | |
| 2630 ErrorMsg(method->name_pos, | |
| 2631 "function body not allowed in interface declaration"); | |
| 2632 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 2597 } else if (method->IsFactoryOrConstructor() && method->has_const) { |
| 2633 ErrorMsg(method->name_pos, | 2598 ErrorMsg(method->name_pos, |
| 2634 "const constructor or factory '%s' may not be native", | 2599 "const constructor or factory '%s' may not be native", |
| 2635 method->name->ToCString()); | 2600 method->name->ToCString()); |
| 2636 } | 2601 } |
| 2637 if (method->redirect_name != NULL) { | 2602 if (method->redirect_name != NULL) { |
| 2638 ErrorMsg(method->name_pos, | 2603 ErrorMsg(method->name_pos, |
| 2639 "Constructor with redirection may not have a function body"); | 2604 "Constructor with redirection may not have a function body"); |
| 2640 } | 2605 } |
| 2641 ParseNativeDeclaration(); | 2606 ParseNativeDeclaration(); |
| 2642 } else { | 2607 } else { |
| 2643 // We haven't found a method body. Issue error if one is required. | 2608 // We haven't found a method body. Issue error if one is required. |
| 2644 const bool must_have_body = | 2609 const bool must_have_body = |
| 2645 !members->is_interface() && | |
| 2646 method->has_static && | 2610 method->has_static && |
| 2647 !method->has_external && | 2611 !method->has_external && |
| 2648 redirection_type.IsNull(); | 2612 redirection_type.IsNull(); |
| 2649 if (must_have_body) { | 2613 if (must_have_body) { |
| 2650 ErrorMsg(method->name_pos, | 2614 ErrorMsg(method->name_pos, |
| 2651 "function body expected for method '%s'", | 2615 "function body expected for method '%s'", |
| 2652 method->name->ToCString()); | 2616 method->name->ToCString()); |
| 2653 } | 2617 } |
| 2654 | 2618 |
| 2655 if (CurrentToken() == Token::kSEMICOLON) { | 2619 if (CurrentToken() == Token::kSEMICOLON) { |
| 2656 ConsumeToken(); | 2620 ConsumeToken(); |
| 2657 if (!members->is_interface() && | 2621 if (!method->has_static && |
| 2658 !method->has_static && | |
| 2659 !method->has_external && | 2622 !method->has_external && |
| 2660 !method->IsConstructor()) { | 2623 !method->IsConstructor()) { |
| 2661 // Methods, getters and setters without a body are | 2624 // Methods, getters and setters without a body are |
| 2662 // implicitly abstract. | 2625 // implicitly abstract. |
| 2663 method->has_abstract = true; | 2626 method->has_abstract = true; |
| 2664 } | 2627 } |
| 2665 } else { | 2628 } else { |
| 2666 // Signature is not followed by semicolon or body. Issue an | 2629 // Signature is not followed by semicolon or body. Issue an |
| 2667 // appropriate error. | 2630 // appropriate error. |
| 2668 const bool must_have_semicolon = | 2631 const bool must_have_semicolon = |
| 2669 members->is_interface() || | |
| 2670 (method->redirect_name != NULL) || | 2632 (method->redirect_name != NULL) || |
| 2671 (method->IsConstructor() && method->has_const) || | 2633 (method->IsConstructor() && method->has_const) || |
| 2672 method->has_external; | 2634 method->has_external; |
| 2673 if (must_have_semicolon) { | 2635 if (must_have_semicolon) { |
| 2674 ExpectSemicolon(); | 2636 ExpectSemicolon(); |
| 2675 } else { | 2637 } else { |
| 2676 ErrorMsg(method->name_pos, | 2638 ErrorMsg(method->name_pos, |
| 2677 "function body or semicolon expected for method '%s'", | 2639 "function body or semicolon expected for method '%s'", |
| 2678 method->name->ToCString()); | 2640 method->name->ToCString()); |
| 2679 } | 2641 } |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3060 } else if (IsIdentifier()) { | 3022 } else if (IsIdentifier()) { |
| 3061 member.name = CurrentLiteral(); | 3023 member.name = CurrentLiteral(); |
| 3062 member.name_pos = TokenPos(); | 3024 member.name_pos = TokenPos(); |
| 3063 ConsumeToken(); | 3025 ConsumeToken(); |
| 3064 } else { | 3026 } else { |
| 3065 ErrorMsg("identifier expected"); | 3027 ErrorMsg("identifier expected"); |
| 3066 } | 3028 } |
| 3067 | 3029 |
| 3068 ASSERT(member.name != NULL); | 3030 ASSERT(member.name != NULL); |
| 3069 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { | 3031 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { |
| 3070 if (members->is_interface() && member.has_static) { | |
| 3071 if (member.has_factory) { | |
| 3072 ErrorMsg("factory constructors are not allowed in interfaces"); | |
| 3073 } else { | |
| 3074 ErrorMsg("static methods are not allowed in interfaces"); | |
| 3075 } | |
| 3076 } | |
| 3077 // Constructor or method. | 3032 // Constructor or method. |
| 3078 if (member.type == NULL) { | 3033 if (member.type == NULL) { |
| 3079 member.type = &Type::ZoneHandle(Type::DynamicType()); | 3034 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 3080 } | 3035 } |
| 3081 ASSERT(member.IsFactory() == member.has_factory); | 3036 ASSERT(member.IsFactory() == member.has_factory); |
| 3082 ParseMethodOrConstructor(members, &member); | 3037 ParseMethodOrConstructor(members, &member); |
| 3083 } else if (CurrentToken() == Token::kSEMICOLON || | 3038 } else if (CurrentToken() == Token::kSEMICOLON || |
| 3084 CurrentToken() == Token::kCOMMA || | 3039 CurrentToken() == Token::kCOMMA || |
| 3085 CurrentToken() == Token::kASSIGN) { | 3040 CurrentToken() == Token::kASSIGN) { |
| 3086 // Field definition. | 3041 // Field definition. |
| 3087 if (member.has_const) { | 3042 if (member.has_const) { |
| 3088 // const fields are implicitly final. | 3043 // const fields are implicitly final. |
| 3089 member.has_final = true; | 3044 member.has_final = true; |
| 3090 } | 3045 } |
| 3091 if (member.type == NULL) { | 3046 if (member.type == NULL) { |
| 3092 if (member.has_final) { | 3047 if (member.has_final) { |
| 3093 member.type = &Type::ZoneHandle(Type::DynamicType()); | 3048 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 3094 } else { | 3049 } else { |
| 3095 ErrorMsg("missing 'var', 'final', 'const' or type" | 3050 ErrorMsg("missing 'var', 'final', 'const' or type" |
| 3096 " in field declaration"); | 3051 " in field declaration"); |
| 3097 } | 3052 } |
| 3098 } | 3053 } |
| 3099 if (members->is_interface() && member.has_static && !member.has_final) { | |
| 3100 ErrorMsg("static non-final fields are not allowed in interfaces"); | |
| 3101 } | |
| 3102 ParseFieldDefinition(members, &member); | 3054 ParseFieldDefinition(members, &member); |
| 3103 } else { | 3055 } else { |
| 3104 UnexpectedToken(); | 3056 UnexpectedToken(); |
| 3105 } | 3057 } |
| 3106 current_member_ = NULL; | 3058 current_member_ = NULL; |
| 3107 members->AddMember(member); | 3059 members->AddMember(member); |
| 3108 } | 3060 } |
| 3109 | 3061 |
| 3110 | 3062 |
| 3111 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { | 3063 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3136 class_name.ToCString()); | 3088 class_name.ToCString()); |
| 3137 } | 3089 } |
| 3138 cls = Class::New(class_name, script_, classname_pos); | 3090 cls = Class::New(class_name, script_, classname_pos); |
| 3139 library_.AddClass(cls); | 3091 library_.AddClass(cls); |
| 3140 } else { | 3092 } else { |
| 3141 if (!obj.IsClass()) { | 3093 if (!obj.IsClass()) { |
| 3142 ErrorMsg(classname_pos, "'%s' is already defined", | 3094 ErrorMsg(classname_pos, "'%s' is already defined", |
| 3143 class_name.ToCString()); | 3095 class_name.ToCString()); |
| 3144 } | 3096 } |
| 3145 cls ^= obj.raw(); | 3097 cls ^= obj.raw(); |
| 3146 if (cls.is_interface()) { | 3098 if (is_patch) { |
| 3147 ErrorMsg(classname_pos, "'%s' %s", | |
| 3148 class_name.ToCString(), | |
| 3149 is_patch ? | |
| 3150 "interface cannot be patched" : | |
| 3151 "is already defined as interface"); | |
| 3152 } else if (is_patch) { | |
| 3153 String& patch = String::Handle(Symbols::New("patch ")); | 3099 String& patch = String::Handle(Symbols::New("patch ")); |
| 3154 patch = String::Concat(patch, class_name); | 3100 patch = String::Concat(patch, class_name); |
| 3155 patch = Symbols::New(patch); | 3101 patch = Symbols::New(patch); |
| 3156 cls = Class::New(patch, script_, classname_pos); | 3102 cls = Class::New(patch, script_, classname_pos); |
| 3157 cls.set_library(library_); | 3103 cls.set_library(library_); |
| 3158 } else { | 3104 } else { |
| 3159 // Not patching a class, but it has been found. This must be one of the | 3105 // Not patching a class, but it has been found. This must be one of the |
| 3160 // pre-registered classes from object.cc or a duplicate definition. | 3106 // pre-registered classes from object.cc or a duplicate definition. |
| 3161 if (cls.functions() != Object::empty_array()) { | 3107 if (cls.functions() != Object::empty_array()) { |
| 3162 ErrorMsg(classname_pos, "class '%s' is already defined", | 3108 ErrorMsg(classname_pos, "class '%s' is already defined", |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3176 const intptr_t type_pos = TokenPos(); | 3122 const intptr_t type_pos = TokenPos(); |
| 3177 const AbstractType& type = AbstractType::Handle( | 3123 const AbstractType& type = AbstractType::Handle( |
| 3178 ParseType(ClassFinalizer::kTryResolve)); | 3124 ParseType(ClassFinalizer::kTryResolve)); |
| 3179 if (type.IsTypeParameter()) { | 3125 if (type.IsTypeParameter()) { |
| 3180 ErrorMsg(type_pos, | 3126 ErrorMsg(type_pos, |
| 3181 "class '%s' may not extend type parameter '%s'", | 3127 "class '%s' may not extend type parameter '%s'", |
| 3182 class_name.ToCString(), | 3128 class_name.ToCString(), |
| 3183 String::Handle(type.UserVisibleName()).ToCString()); | 3129 String::Handle(type.UserVisibleName()).ToCString()); |
| 3184 } | 3130 } |
| 3185 super_type ^= type.raw(); | 3131 super_type ^= type.raw(); |
| 3186 if (super_type.IsInterfaceType()) { | |
| 3187 ErrorMsg(type_pos, | |
| 3188 "class '%s' may implement, but cannot extend interface '%s'", | |
| 3189 class_name.ToCString(), | |
| 3190 String::Handle(super_type.UserVisibleName()).ToCString()); | |
| 3191 } | |
| 3192 } else { | 3132 } else { |
| 3193 // No extends clause: Implicitly extend Object. | 3133 // No extends clause: Implicitly extend Object. |
| 3194 super_type = Type::ObjectType(); | 3134 super_type = Type::ObjectType(); |
| 3195 } | 3135 } |
| 3196 ASSERT(!super_type.IsNull()); | 3136 ASSERT(!super_type.IsNull()); |
| 3197 cls.set_super_type(super_type); | 3137 cls.set_super_type(super_type); |
| 3198 | 3138 |
| 3199 if (CurrentToken() == Token::kIMPLEMENTS) { | 3139 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3200 Array& interfaces = Array::Handle(); | 3140 Array& interfaces = Array::Handle(); |
| 3201 const intptr_t interfaces_pos = TokenPos(); | 3141 const intptr_t interfaces_pos = TokenPos(); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3338 SetPosition(saved_pos); | 3278 SetPosition(saved_pos); |
| 3339 return is_alias_name; | 3279 return is_alias_name; |
| 3340 } | 3280 } |
| 3341 | 3281 |
| 3342 | 3282 |
| 3343 void Parser::ParseFunctionTypeAlias( | 3283 void Parser::ParseFunctionTypeAlias( |
| 3344 const GrowableObjectArray& pending_classes) { | 3284 const GrowableObjectArray& pending_classes) { |
| 3345 TRACE_PARSER("ParseFunctionTypeAlias"); | 3285 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 3346 ExpectToken(Token::kTYPEDEF); | 3286 ExpectToken(Token::kTYPEDEF); |
| 3347 | 3287 |
| 3348 // Allocate an interface to hold the type parameters and their bounds. | 3288 // Allocate an abstract class to hold the type parameters and their bounds. |
| 3349 // Make it the owner of the function type descriptor. | 3289 // Make it the owner of the function type descriptor. |
| 3350 const Class& alias_owner = Class::Handle( | 3290 const Class& alias_owner = Class::Handle( |
| 3351 Class::New(String::Handle(Symbols::New(":alias_owner")), | 3291 Class::New(String::Handle(Symbols::New(":alias_owner")), |
| 3352 Script::Handle(), | 3292 Script::Handle(), |
| 3353 TokenPos())); | 3293 TokenPos())); |
| 3354 alias_owner.set_is_interface(); | 3294 |
| 3295 alias_owner.set_is_abstract(); |
| 3355 alias_owner.set_library(library_); | 3296 alias_owner.set_library(library_); |
| 3356 set_current_class(alias_owner); | 3297 set_current_class(alias_owner); |
| 3357 | 3298 |
| 3358 // Parse the result type of the function type. | 3299 // Parse the result type of the function type. |
| 3359 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3300 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3360 if (CurrentToken() == Token::kVOID) { | 3301 if (CurrentToken() == Token::kVOID) { |
| 3361 ConsumeToken(); | 3302 ConsumeToken(); |
| 3362 result_type = Type::VoidType(); | 3303 result_type = Type::VoidType(); |
| 3363 } else if (!IsFunctionTypeAliasName()) { | 3304 } else if (!IsFunctionTypeAliasName()) { |
| 3364 // Type annotations in typedef are never ignored, even in unchecked mode. | 3305 // Type annotations in typedef are never ignored, even in unchecked mode. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3444 // This alias should not be marked as finalized yet, since it needs to be | 3385 // This alias should not be marked as finalized yet, since it needs to be |
| 3445 // checked in the class finalizer for illegal self references. | 3386 // checked in the class finalizer for illegal self references. |
| 3446 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); | 3387 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); |
| 3447 ASSERT(!function_type_alias.is_finalized()); | 3388 ASSERT(!function_type_alias.is_finalized()); |
| 3448 library_.AddClass(function_type_alias); | 3389 library_.AddClass(function_type_alias); |
| 3449 ExpectSemicolon(); | 3390 ExpectSemicolon(); |
| 3450 pending_classes.Add(function_type_alias, Heap::kOld); | 3391 pending_classes.Add(function_type_alias, Heap::kOld); |
| 3451 } | 3392 } |
| 3452 | 3393 |
| 3453 | 3394 |
| 3454 // TODO(regis): Remove support for interfaces. | |
| 3455 void Parser::ParseInterfaceDefinition( | |
| 3456 const GrowableObjectArray& pending_classes) { | |
| 3457 TRACE_PARSER("ParseInterfaceDefinition"); | |
| 3458 const intptr_t interface_pos = TokenPos(); | |
| 3459 ExpectToken(Token::kINTERFACE); | |
| 3460 const intptr_t interfacename_pos = TokenPos(); | |
| 3461 String& interface_name = | |
| 3462 *ExpectUserDefinedTypeIdentifier("interface name expected"); | |
| 3463 if (FLAG_trace_parser) { | |
| 3464 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | |
| 3465 } | |
| 3466 Class& interface = Class::Handle(); | |
| 3467 Object& obj = Object::Handle(library_.LookupLocalObject(interface_name)); | |
| 3468 if (obj.IsNull()) { | |
| 3469 interface = Class::NewInterface(interface_name, script_, interfacename_pos); | |
| 3470 library_.AddClass(interface); | |
| 3471 } else { | |
| 3472 if (!obj.IsClass()) { | |
| 3473 ErrorMsg(interfacename_pos, "'%s' is already defined", | |
| 3474 interface_name.ToCString()); | |
| 3475 } | |
| 3476 interface ^= obj.raw(); | |
| 3477 if (!interface.is_interface()) { | |
| 3478 ErrorMsg(interfacename_pos, | |
| 3479 "'%s' is already defined as class", | |
| 3480 interface_name.ToCString()); | |
| 3481 } else if (interface.functions() != Object::empty_array()) { | |
| 3482 ErrorMsg(interfacename_pos, | |
| 3483 "interface '%s' is already defined", | |
| 3484 interface_name.ToCString()); | |
| 3485 } | |
| 3486 } | |
| 3487 ASSERT(!interface.IsNull()); | |
| 3488 ASSERT(interface.functions() == Object::empty_array()); | |
| 3489 set_current_class(interface); | |
| 3490 ParseTypeParameters(interface); | |
| 3491 | |
| 3492 if (CurrentToken() == Token::kEXTENDS) { | |
| 3493 Array& interfaces = Array::Handle(); | |
| 3494 const intptr_t interfaces_pos = TokenPos(); | |
| 3495 interfaces = ParseInterfaceList(); | |
| 3496 AddInterfaces(interfaces_pos, interface, interfaces); | |
| 3497 } | |
| 3498 | |
| 3499 ExpectToken(Token::kLBRACE); | |
| 3500 ClassDesc members(interface, interface_name, true, interface_pos); | |
| 3501 while (CurrentToken() != Token::kRBRACE) { | |
| 3502 ParseClassMemberDefinition(&members); | |
| 3503 } | |
| 3504 ExpectToken(Token::kRBRACE); | |
| 3505 | |
| 3506 if (members.has_constructor()) { | |
| 3507 ErrorMsg(interfacename_pos, | |
| 3508 "interface '%s' cannot declare constructor", | |
| 3509 interface_name.ToCString()); | |
| 3510 } | |
| 3511 | |
| 3512 Array& array = Array::Handle(); | |
| 3513 array = Array::MakeArray(members.fields()); | |
| 3514 interface.SetFields(array); | |
| 3515 | |
| 3516 // Creating a new array for functions marks the interface as parsed. | |
| 3517 array = Array::MakeArray(members.functions()); | |
| 3518 interface.SetFunctions(array); | |
| 3519 ASSERT(interface.is_interface()); | |
| 3520 | |
| 3521 pending_classes.Add(interface, Heap::kOld); | |
| 3522 } | |
| 3523 | |
| 3524 | |
| 3525 // Consumes exactly one right angle bracket. If the current token is a single | 3395 // Consumes exactly one right angle bracket. If the current token is a single |
| 3526 // bracket token, it is consumed normally. However, if it is a double or triple | 3396 // bracket token, it is consumed normally. However, if it is a double or triple |
| 3527 // bracket, it is replaced by a single or double bracket token without | 3397 // bracket, it is replaced by a single or double bracket token without |
| 3528 // incrementing the token index. | 3398 // incrementing the token index. |
| 3529 void Parser::ConsumeRightAngleBracket() { | 3399 void Parser::ConsumeRightAngleBracket() { |
| 3530 if (token_kind_ == Token::kGT) { | 3400 if (token_kind_ == Token::kGT) { |
| 3531 ConsumeToken(); | 3401 ConsumeToken(); |
| 3532 } else if (token_kind_ == Token::kSHR) { | 3402 } else if (token_kind_ == Token::kSHR) { |
| 3533 token_kind_ = Token::kGT; | 3403 token_kind_ = Token::kGT; |
| 3534 } else { | 3404 } else { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3766 Array& cls_interfaces = Array::Handle(cls.interfaces()); | 3636 Array& cls_interfaces = Array::Handle(cls.interfaces()); |
| 3767 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 3637 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 3768 interface ^= cls_interfaces.At(i); | 3638 interface ^= cls_interfaces.At(i); |
| 3769 all_interfaces.Add(interface); | 3639 all_interfaces.Add(interface); |
| 3770 } | 3640 } |
| 3771 // Now add the new interfaces. | 3641 // Now add the new interfaces. |
| 3772 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 3642 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 3773 AbstractType& interface = AbstractType::ZoneHandle(); | 3643 AbstractType& interface = AbstractType::ZoneHandle(); |
| 3774 interface ^= interfaces.At(i); | 3644 interface ^= interfaces.At(i); |
| 3775 if (interface.IsTypeParameter()) { | 3645 if (interface.IsTypeParameter()) { |
| 3776 if (cls.is_interface()) { | 3646 ErrorMsg(interfaces_pos, |
| 3777 ErrorMsg(interfaces_pos, | 3647 "class '%s' may not implement type parameter '%s'", |
| 3778 "interface '%s' may not extend type parameter '%s'", | 3648 String::Handle(cls.Name()).ToCString(), |
| 3779 String::Handle(cls.Name()).ToCString(), | 3649 String::Handle(interface.UserVisibleName()).ToCString()); |
| 3780 String::Handle(interface.UserVisibleName()).ToCString()); | |
| 3781 } else { | |
| 3782 ErrorMsg(interfaces_pos, | |
| 3783 "class '%s' may not implement type parameter '%s'", | |
| 3784 String::Handle(cls.Name()).ToCString(), | |
| 3785 String::Handle(interface.UserVisibleName()).ToCString()); | |
| 3786 } | |
| 3787 } | 3650 } |
| 3788 AddInterfaceIfUnique(interfaces_pos, all_interfaces, interface); | 3651 AddInterfaceIfUnique(interfaces_pos, all_interfaces, interface); |
| 3789 } | 3652 } |
| 3790 cls_interfaces = Array::MakeArray(all_interfaces); | 3653 cls_interfaces = Array::MakeArray(all_interfaces); |
| 3791 cls.set_interfaces(cls_interfaces); | 3654 cls.set_interfaces(cls_interfaces); |
| 3792 } | 3655 } |
| 3793 | 3656 |
| 3794 | 3657 |
| 3795 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3658 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3796 TRACE_PARSER("ParseTopLevelVariable"); | 3659 TRACE_PARSER("ParseTopLevelVariable"); |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4456 } | 4319 } |
| 4457 | 4320 |
| 4458 while (true) { | 4321 while (true) { |
| 4459 set_current_class(Class::Handle()); // No current class. | 4322 set_current_class(Class::Handle()); // No current class. |
| 4460 SkipMetadata(); | 4323 SkipMetadata(); |
| 4461 if (CurrentToken() == Token::kCLASS) { | 4324 if (CurrentToken() == Token::kCLASS) { |
| 4462 ParseClassDefinition(pending_classes); | 4325 ParseClassDefinition(pending_classes); |
| 4463 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4326 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4464 (LookaheadToken(1) != Token::kLPAREN)) { | 4327 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4465 ParseFunctionTypeAlias(pending_classes); | 4328 ParseFunctionTypeAlias(pending_classes); |
| 4466 } else if (CurrentToken() == Token::kINTERFACE) { | |
| 4467 ParseInterfaceDefinition(pending_classes); | |
| 4468 } else if ((CurrentToken() == Token::kABSTRACT) && | 4329 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4469 (LookaheadToken(1) == Token::kCLASS)) { | 4330 (LookaheadToken(1) == Token::kCLASS)) { |
| 4470 ParseClassDefinition(pending_classes); | 4331 ParseClassDefinition(pending_classes); |
| 4471 } else if (is_patch_source() && IsLiteral("patch") && | 4332 } else if (is_patch_source() && IsLiteral("patch") && |
| 4472 (LookaheadToken(1) == Token::kCLASS)) { | 4333 (LookaheadToken(1) == Token::kCLASS)) { |
| 4473 ParseClassDefinition(pending_classes); | 4334 ParseClassDefinition(pending_classes); |
| 4474 } else { | 4335 } else { |
| 4475 set_current_class(toplevel_class); | 4336 set_current_class(toplevel_class); |
| 4476 if (IsVariableDeclaration()) { | 4337 if (IsVariableDeclaration()) { |
| 4477 ParseTopLevelVariable(&top_level); | 4338 ParseTopLevelVariable(&top_level); |
| (...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5866 ArgumentListNode* arguments) { | 5727 ArgumentListNode* arguments) { |
| 5867 const Class& cls = Class::Handle(LookupCoreClass(cls_name)); | 5728 const Class& cls = Class::Handle(LookupCoreClass(cls_name)); |
| 5868 ASSERT(!cls.IsNull()); | 5729 ASSERT(!cls.IsNull()); |
| 5869 const Function& func = Function::ZoneHandle( | 5730 const Function& func = Function::ZoneHandle( |
| 5870 Resolver::ResolveStatic(cls, | 5731 Resolver::ResolveStatic(cls, |
| 5871 func_name, | 5732 func_name, |
| 5872 arguments->length(), | 5733 arguments->length(), |
| 5873 arguments->names(), | 5734 arguments->names(), |
| 5874 Resolver::kIsQualified)); | 5735 Resolver::kIsQualified)); |
| 5875 ASSERT(!func.IsNull()); | 5736 ASSERT(!func.IsNull()); |
| 5876 CheckFunctionIsCallable(arguments->token_pos(), func); | |
| 5877 return new StaticCallNode(arguments->token_pos(), func, arguments); | 5737 return new StaticCallNode(arguments->token_pos(), func, arguments); |
| 5878 } | 5738 } |
| 5879 | 5739 |
| 5880 | 5740 |
| 5881 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 5741 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { |
| 5882 ArgumentListNode* arguments = new ArgumentListNode(begin); | 5742 ArgumentListNode* arguments = new ArgumentListNode(begin); |
| 5883 arguments->Add(new LiteralNode(begin, | 5743 arguments->Add(new LiteralNode(begin, |
| 5884 Integer::ZoneHandle(Integer::New(begin)))); | 5744 Integer::ZoneHandle(Integer::New(begin)))); |
| 5885 arguments->Add(new LiteralNode(end, | 5745 arguments->Add(new LiteralNode(end, |
| 5886 Integer::ZoneHandle(Integer::New(end)))); | 5746 Integer::ZoneHandle(Integer::New(end)))); |
| (...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7304 return new ClosureCallNode(call_pos, closure, arguments); | 7164 return new ClosureCallNode(call_pos, closure, arguments); |
| 7305 } | 7165 } |
| 7306 } else { | 7166 } else { |
| 7307 EnsureExpressionTemp(); | 7167 EnsureExpressionTemp(); |
| 7308 closure = GenerateStaticFieldLookup(field, call_pos); | 7168 closure = GenerateStaticFieldLookup(field, call_pos); |
| 7309 return new ClosureCallNode(call_pos, closure, arguments); | 7169 return new ClosureCallNode(call_pos, closure, arguments); |
| 7310 } | 7170 } |
| 7311 // Could not resolve static method: throw a NoSuchMethodError. | 7171 // Could not resolve static method: throw a NoSuchMethodError. |
| 7312 return ThrowNoSuchMethodError(ident_pos, func_name); | 7172 return ThrowNoSuchMethodError(ident_pos, func_name); |
| 7313 } | 7173 } |
| 7314 CheckFunctionIsCallable(call_pos, func); | |
| 7315 return new StaticCallNode(call_pos, func, arguments); | 7174 return new StaticCallNode(call_pos, func, arguments); |
| 7316 } | 7175 } |
| 7317 | 7176 |
| 7318 | 7177 |
| 7319 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 7178 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
| 7320 TRACE_PARSER("ParseInstanceCall"); | 7179 TRACE_PARSER("ParseInstanceCall"); |
| 7321 const intptr_t call_pos = TokenPos(); | 7180 const intptr_t call_pos = TokenPos(); |
| 7322 if (CurrentToken() != Token::kLPAREN) { | 7181 if (CurrentToken() != Token::kLPAREN) { |
| 7323 ErrorMsg(call_pos, "left parenthesis expected"); | 7182 ErrorMsg(call_pos, "left parenthesis expected"); |
| 7324 } | 7183 } |
| (...skipping 1747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9072 } | 8931 } |
| 9073 return ThrowTypeError(type_pos, type); | 8932 return ThrowTypeError(type_pos, type); |
| 9074 } | 8933 } |
| 9075 | 8934 |
| 9076 // Resolve the type and optional identifier to a constructor or factory. | 8935 // Resolve the type and optional identifier to a constructor or factory. |
| 9077 Class& type_class = Class::Handle(type.type_class()); | 8936 Class& type_class = Class::Handle(type.type_class()); |
| 9078 const String& type_class_name = String::Handle(type_class.Name()); | 8937 const String& type_class_name = String::Handle(type_class.Name()); |
| 9079 AbstractTypeArguments& type_arguments = | 8938 AbstractTypeArguments& type_arguments = |
| 9080 AbstractTypeArguments::ZoneHandle(type.arguments()); | 8939 AbstractTypeArguments::ZoneHandle(type.arguments()); |
| 9081 | 8940 |
| 9082 // The constructor class and its name are those of the parsed type, unless the | |
| 9083 // parsed type is an interface and a default factory class is specified, in | |
| 9084 // which case constructor_class and constructor_class_name are modified below. | |
| 9085 Class& constructor_class = Class::ZoneHandle(type_class.raw()); | |
| 9086 String& constructor_class_name = String::Handle(type_class_name.raw()); | |
| 9087 | |
| 9088 // A constructor has an implicit 'this' parameter (instance to construct) | 8941 // A constructor has an implicit 'this' parameter (instance to construct) |
| 9089 // and a factory has an implicit 'this' parameter (type_arguments). | 8942 // and a factory has an implicit 'this' parameter (type_arguments). |
| 9090 // A constructor has a second implicit 'phase' parameter. | 8943 // A constructor has a second implicit 'phase' parameter. |
| 9091 intptr_t arguments_length = arguments->length() + 2; | 8944 intptr_t arguments_length = arguments->length() + 2; |
| 9092 | 8945 |
| 9093 if (type_class.is_interface()) { | |
| 9094 // TODO(regis): Remove support for interfaces. | |
| 9095 UNREACHABLE(); | |
| 9096 } | |
| 9097 | |
| 9098 // An additional type check of the result of a redirecting factory may be | 8946 // An additional type check of the result of a redirecting factory may be |
| 9099 // required. | 8947 // required. |
| 9100 AbstractType& type_bound = AbstractType::ZoneHandle(); | 8948 AbstractType& type_bound = AbstractType::ZoneHandle(); |
| 9101 | 8949 |
| 9102 // Make sure that an appropriate constructor exists. | 8950 // Make sure that an appropriate constructor exists. |
| 9103 const String& constructor_name = | 8951 const String& constructor_name = |
| 9104 BuildConstructorName(constructor_class_name, named_constructor); | 8952 BuildConstructorName(type_class_name, named_constructor); |
| 9105 Function& constructor = Function::ZoneHandle( | 8953 Function& constructor = Function::ZoneHandle( |
| 9106 constructor_class.LookupConstructor(constructor_name)); | 8954 type_class.LookupConstructor(constructor_name)); |
| 9107 if (constructor.IsNull()) { | 8955 if (constructor.IsNull()) { |
| 9108 constructor = constructor_class.LookupFactory(constructor_name); | 8956 constructor = type_class.LookupFactory(constructor_name); |
| 9109 if (constructor.IsNull()) { | 8957 if (constructor.IsNull()) { |
| 9110 const String& external_constructor_name = | 8958 const String& external_constructor_name = |
| 9111 (named_constructor ? constructor_name : constructor_class_name); | 8959 (named_constructor ? constructor_name : type_class_name); |
| 9112 // Replace the type with a malformed type and compile a throw or report a | 8960 // Replace the type with a malformed type and compile a throw or report a |
| 9113 // compile-time error if the constructor is const. | 8961 // compile-time error if the constructor is const. |
| 9114 type = ClassFinalizer::NewFinalizedMalformedType( | 8962 type = ClassFinalizer::NewFinalizedMalformedType( |
| 9115 Error::Handle(), // No previous error. | 8963 Error::Handle(), // No previous error. |
| 9116 current_class(), | 8964 current_class(), |
| 9117 call_pos, | 8965 call_pos, |
| 9118 ClassFinalizer::kTryResolve, // No compile-time error. | 8966 ClassFinalizer::kTryResolve, // No compile-time error. |
| 9119 "class '%s' has no constructor or factory named '%s'", | 8967 "class '%s' has no constructor or factory named '%s'", |
| 9120 String::Handle(constructor_class.Name()).ToCString(), | 8968 String::Handle(type_class.Name()).ToCString(), |
| 9121 external_constructor_name.ToCString()); | 8969 external_constructor_name.ToCString()); |
| 9122 if (is_const) { | 8970 if (is_const) { |
| 9123 const Error& error = Error::Handle(type.malformed_error()); | 8971 const Error& error = Error::Handle(type.malformed_error()); |
| 9124 ErrorMsg(error); | 8972 ErrorMsg(error); |
| 9125 } | 8973 } |
| 9126 return ThrowNoSuchMethodError(call_pos, external_constructor_name); | 8974 return ThrowNoSuchMethodError(call_pos, external_constructor_name); |
| 9127 } else if (constructor.IsRedirectingFactory()) { | 8975 } else if (constructor.IsRedirectingFactory()) { |
| 9128 Type& redirect_type = Type::Handle(constructor.RedirectionType()); | 8976 Type& redirect_type = Type::Handle(constructor.RedirectionType()); |
| 9129 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) { | 8977 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) { |
| 9130 // The type arguments of the redirection type are instantiated from the | 8978 // The type arguments of the redirection type are instantiated from the |
| 9131 // type arguments of the parsed type of the 'new' or 'const' expression. | 8979 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 9132 redirect_type ^= redirect_type.InstantiateFrom(type_arguments); | 8980 redirect_type ^= redirect_type.InstantiateFrom(type_arguments); |
| 9133 } | 8981 } |
| 9134 if (redirect_type.IsMalformed()) { | 8982 if (redirect_type.IsMalformed()) { |
| 9135 if (is_const) { | 8983 if (is_const) { |
| 9136 const Error& error = Error::Handle(redirect_type.malformed_error()); | 8984 const Error& error = Error::Handle(redirect_type.malformed_error()); |
| 9137 ErrorMsg(error); | 8985 ErrorMsg(error); |
| 9138 } | 8986 } |
| 9139 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 8987 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
| 9140 } | 8988 } |
| 9141 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { | 8989 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { |
| 9142 // Additional type checking of the result is necessary. | 8990 // Additional type checking of the result is necessary. |
| 9143 type_bound = type.raw(); | 8991 type_bound = type.raw(); |
| 9144 } | 8992 } |
| 9145 type = redirect_type.raw(); | 8993 type = redirect_type.raw(); |
| 9146 type_class = type.type_class(); | 8994 type_class = type.type_class(); |
| 9147 type_arguments = type.arguments(); | 8995 type_arguments = type.arguments(); |
| 9148 constructor = constructor.RedirectionTarget(); | 8996 constructor = constructor.RedirectionTarget(); |
| 9149 ASSERT(!constructor.IsNull()); | 8997 ASSERT(!constructor.IsNull()); |
| 9150 constructor_class = constructor.Owner(); | |
| 9151 ASSERT(type_class.raw() == constructor_class.raw()); | |
| 9152 } | 8998 } |
| 9153 if (constructor.IsFactory()) { | 8999 if (constructor.IsFactory()) { |
| 9154 // A factory does not have the implicit 'phase' parameter. | 9000 // A factory does not have the implicit 'phase' parameter. |
| 9155 arguments_length -= 1; | 9001 arguments_length -= 1; |
| 9156 } | 9002 } |
| 9157 } | 9003 } |
| 9158 | 9004 |
| 9159 // It is ok to call a factory method of an abstract class, but it is | 9005 // It is ok to call a factory method of an abstract class, but it is |
| 9160 // a dynamic error to instantiate an abstract class. | 9006 // a dynamic error to instantiate an abstract class. |
| 9161 ASSERT(!constructor.IsNull()); | 9007 ASSERT(!constructor.IsNull()); |
| 9162 if (constructor_class.is_abstract() && !constructor.IsFactory()) { | 9008 if (type_class.is_abstract() && !constructor.IsFactory()) { |
| 9163 ArgumentListNode* arguments = new ArgumentListNode(type_pos); | 9009 ArgumentListNode* arguments = new ArgumentListNode(type_pos); |
| 9164 arguments->Add(new LiteralNode( | 9010 arguments->Add(new LiteralNode( |
| 9165 TokenPos(), Integer::ZoneHandle(Integer::New(type_pos)))); | 9011 TokenPos(), Integer::ZoneHandle(Integer::New(type_pos)))); |
| 9166 arguments->Add(new LiteralNode( | 9012 arguments->Add(new LiteralNode( |
| 9167 TokenPos(), String::ZoneHandle(constructor_class_name.raw()))); | 9013 TokenPos(), String::ZoneHandle(type_class_name.raw()))); |
| 9168 const String& cls_name = | 9014 const String& cls_name = |
| 9169 String::Handle(Symbols::AbstractClassInstantiationError()); | 9015 String::Handle(Symbols::AbstractClassInstantiationError()); |
| 9170 const String& func_name = String::Handle(Symbols::ThrowNew()); | 9016 const String& func_name = String::Handle(Symbols::ThrowNew()); |
| 9171 return MakeStaticCall(cls_name, func_name, arguments); | 9017 return MakeStaticCall(cls_name, func_name, arguments); |
| 9172 } | 9018 } |
| 9173 String& error_message = String::Handle(); | 9019 String& error_message = String::Handle(); |
| 9174 if (!constructor.AreValidArguments(arguments_length, | 9020 if (!constructor.AreValidArguments(arguments_length, |
| 9175 arguments->names(), | 9021 arguments->names(), |
| 9176 &error_message)) { | 9022 &error_message)) { |
| 9177 const String& external_constructor_name = | 9023 const String& external_constructor_name = |
| 9178 (named_constructor ? constructor_name : constructor_class_name); | 9024 (named_constructor ? constructor_name : type_class_name); |
| 9179 if (is_const) { | 9025 if (is_const) { |
| 9180 ErrorMsg(call_pos, | 9026 ErrorMsg(call_pos, |
| 9181 "invalid arguments passed to constructor '%s' " | 9027 "invalid arguments passed to constructor '%s' " |
| 9182 "for class '%s': %s", | 9028 "for class '%s': %s", |
| 9183 external_constructor_name.ToCString(), | 9029 external_constructor_name.ToCString(), |
| 9184 String::Handle(constructor_class.Name()).ToCString(), | 9030 String::Handle(type_class.Name()).ToCString(), |
| 9185 error_message.ToCString()); | 9031 error_message.ToCString()); |
| 9186 } | 9032 } |
| 9187 return ThrowNoSuchMethodError(call_pos, external_constructor_name); | 9033 return ThrowNoSuchMethodError(call_pos, external_constructor_name); |
| 9188 } | 9034 } |
| 9189 | 9035 |
| 9190 // Now that the constructor to be called is identified, finalize the type | |
| 9191 // argument vector to be passed. | |
| 9192 // The type argument vector of the parsed type was finalized in ParseType. | |
| 9193 // If the constructor class was changed from the interface class to the | |
| 9194 // factory class, we need to finalize the type argument vector again, because | |
| 9195 // it may be longer due to the factory class extending a class, or/and because | |
| 9196 // the bounds on the factory class may be tighter than on the interface. | |
| 9197 if (!constructor.IsNull() && (constructor_class.raw() != type_class.raw())) { | |
| 9198 const intptr_t num_type_parameters = constructor_class.NumTypeParameters(); | |
| 9199 TypeArguments& temp_type_arguments = TypeArguments::Handle(); | |
| 9200 if (!type_arguments.IsNull()) { | |
| 9201 // Copy the parsed type arguments starting at offset 0, because interfaces | |
| 9202 // have no super types. | |
| 9203 ASSERT(type_class.NumTypeArguments() == type_class.NumTypeParameters()); | |
| 9204 const intptr_t num_type_arguments = type_arguments.Length(); | |
| 9205 temp_type_arguments = TypeArguments::New(num_type_parameters, Heap::kNew); | |
| 9206 AbstractType& type_argument = AbstractType::Handle(); | |
| 9207 for (intptr_t i = 0; i < num_type_parameters; i++) { | |
| 9208 if (i < num_type_arguments) { | |
| 9209 type_argument = type_arguments.TypeAt(i); | |
| 9210 } else { | |
| 9211 type_argument = Type::DynamicType(); | |
| 9212 } | |
| 9213 temp_type_arguments.SetTypeAt(i, type_argument); | |
| 9214 } | |
| 9215 } | |
| 9216 Type& temp_type = Type::Handle(Type::New( | |
| 9217 constructor_class, temp_type_arguments, type.token_pos(), Heap::kNew)); | |
| 9218 // No need to canonicalize temporary type. | |
| 9219 temp_type ^= ClassFinalizer::FinalizeType( | |
| 9220 current_class(), temp_type, ClassFinalizer::kFinalize); | |
| 9221 // The type argument vector may have been expanded with the type arguments | |
| 9222 // of the super type when finalizing the temporary type. | |
| 9223 type_arguments = temp_type.arguments(); | |
| 9224 // The type parameter bounds of the factory class may be more specific than | |
| 9225 // the type parameter bounds of the interface class. Therefore, although | |
| 9226 // type was not malformed, temp_type may be malformed. | |
| 9227 if (!type.IsMalformed() && temp_type.IsMalformed()) { | |
| 9228 const Error& error = Error::Handle(temp_type.malformed_error()); | |
| 9229 type.set_malformed_error(error); | |
| 9230 } | |
| 9231 } | |
| 9232 // Return a throw in case of a malformed type or report a compile-time error | 9036 // Return a throw in case of a malformed type or report a compile-time error |
| 9233 // if the constructor is const. | 9037 // if the constructor is const. |
| 9234 if (type.IsMalformed()) { | 9038 if (type.IsMalformed()) { |
| 9235 if (is_const) { | 9039 if (is_const) { |
| 9236 const Error& error = Error::Handle(type.malformed_error()); | 9040 const Error& error = Error::Handle(type.malformed_error()); |
| 9237 ErrorMsg(error); | 9041 ErrorMsg(error); |
| 9238 } | 9042 } |
| 9239 return ThrowTypeError(type_pos, type); | 9043 return ThrowTypeError(type_pos, type); |
| 9240 } | 9044 } |
| 9241 type_arguments ^= type_arguments.Canonicalize(); | 9045 type_arguments ^= type_arguments.Canonicalize(); |
| 9242 // Make the constructor call. | 9046 // Make the constructor call. |
| 9243 AstNode* new_object = NULL; | 9047 AstNode* new_object = NULL; |
| 9244 if (is_const) { | 9048 if (is_const) { |
| 9245 if (!constructor.is_const()) { | 9049 if (!constructor.is_const()) { |
| 9246 ErrorMsg("'const' requires const constructor: '%s'", | 9050 ErrorMsg("'const' requires const constructor: '%s'", |
| 9247 String::Handle(constructor.name()).ToCString()); | 9051 String::Handle(constructor.name()).ToCString()); |
| 9248 } | 9052 } |
| 9249 const Object& constructor_result = Object::Handle( | 9053 const Object& constructor_result = Object::Handle( |
| 9250 EvaluateConstConstructorCall(constructor_class, | 9054 EvaluateConstConstructorCall(type_class, |
| 9251 type_arguments, | 9055 type_arguments, |
| 9252 constructor, | 9056 constructor, |
| 9253 arguments)); | 9057 arguments)); |
| 9254 if (constructor_result.IsUnhandledException()) { | 9058 if (constructor_result.IsUnhandledException()) { |
| 9255 new_object = GenerateRethrow(new_pos, constructor_result); | 9059 new_object = GenerateRethrow(new_pos, constructor_result); |
| 9256 } else { | 9060 } else { |
| 9257 const Instance& const_instance = Instance::Cast(constructor_result); | 9061 const Instance& const_instance = Instance::Cast(constructor_result); |
| 9258 new_object = new LiteralNode(new_pos, | 9062 new_object = new LiteralNode(new_pos, |
| 9259 Instance::ZoneHandle(const_instance.raw())); | 9063 Instance::ZoneHandle(const_instance.raw())); |
| 9260 if (!type_bound.IsNull()) { | 9064 if (!type_bound.IsNull()) { |
| 9261 ASSERT(!type_bound.IsMalformed()); | 9065 ASSERT(!type_bound.IsMalformed()); |
| 9262 Error& malformed_error = Error::Handle(); | 9066 Error& malformed_error = Error::Handle(); |
| 9263 if (!const_instance.IsInstanceOf(type_bound, | 9067 if (!const_instance.IsInstanceOf(type_bound, |
| 9264 TypeArguments::Handle(), | 9068 TypeArguments::Handle(), |
| 9265 &malformed_error)) { | 9069 &malformed_error)) { |
| 9266 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 9070 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| 9267 malformed_error, | 9071 malformed_error, |
| 9268 current_class(), | 9072 current_class(), |
| 9269 new_pos, | 9073 new_pos, |
| 9270 ClassFinalizer::kTryResolve, // No compile-time error. | 9074 ClassFinalizer::kTryResolve, // No compile-time error. |
| 9271 "const factory result is not an instance of '%s'", | 9075 "const factory result is not an instance of '%s'", |
| 9272 String::Handle(type_bound.UserVisibleName()).ToCString()); | 9076 String::Handle(type_bound.UserVisibleName()).ToCString()); |
| 9273 new_object = ThrowTypeError(new_pos, type_bound); | 9077 new_object = ThrowTypeError(new_pos, type_bound); |
| 9274 } | 9078 } |
| 9275 type_bound = AbstractType::null(); | 9079 type_bound = AbstractType::null(); |
| 9276 } | 9080 } |
| 9277 } | 9081 } |
| 9278 } else { | 9082 } else { |
| 9279 CheckFunctionIsCallable(new_pos, constructor); | |
| 9280 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 9083 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 9281 if (!type_arguments.IsNull() && | 9084 if (!type_arguments.IsNull() && |
| 9282 !type_arguments.IsInstantiated() && | 9085 !type_arguments.IsInstantiated() && |
| 9283 (current_block_->scope->function_level() > 0)) { | 9086 (current_block_->scope->function_level() > 0)) { |
| 9284 // Make sure that the instantiator is captured. | 9087 // Make sure that the instantiator is captured. |
| 9285 CaptureInstantiator(); | 9088 CaptureInstantiator(); |
| 9286 } | 9089 } |
| 9287 // If the type argument vector is not instantiated, we verify in checked | 9090 // If the type argument vector is not instantiated, we verify in checked |
| 9288 // mode at runtime that it is within its declared bounds. | 9091 // mode at runtime that it is within its declared bounds. |
| 9289 new_object = CreateConstructorCallNode( | 9092 new_object = CreateConstructorCallNode( |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9895 void Parser::SkipQualIdent() { | 9698 void Parser::SkipQualIdent() { |
| 9896 ASSERT(IsIdentifier()); | 9699 ASSERT(IsIdentifier()); |
| 9897 ConsumeToken(); | 9700 ConsumeToken(); |
| 9898 if (CurrentToken() == Token::kPERIOD) { | 9701 if (CurrentToken() == Token::kPERIOD) { |
| 9899 ConsumeToken(); // Consume the kPERIOD token. | 9702 ConsumeToken(); // Consume the kPERIOD token. |
| 9900 ExpectIdentifier("identifier expected after '.'"); | 9703 ExpectIdentifier("identifier expected after '.'"); |
| 9901 } | 9704 } |
| 9902 } | 9705 } |
| 9903 | 9706 |
| 9904 } // namespace dart | 9707 } // namespace dart |
| OLD | NEW |