Chromium Code Reviews| 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 1571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1582 const Class& super_class = Class::Handle(cls.SuperClass()); | 1582 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1583 // Omit the implicit super() if there is no super class (i.e. | 1583 // Omit the implicit super() if there is no super class (i.e. |
| 1584 // we're not compiling class Object), or if the super class is an | 1584 // we're not compiling class Object), or if the super class is an |
| 1585 // artificially generated "wrapper class" that has no constructor. | 1585 // artificially generated "wrapper class" that has no constructor. |
| 1586 if (super_class.IsNull() || | 1586 if (super_class.IsNull() || |
| 1587 (super_class.num_native_fields() > 0 && | 1587 (super_class.num_native_fields() > 0 && |
| 1588 Class::Handle(super_class.SuperClass()).IsObjectClass())) { | 1588 Class::Handle(super_class.SuperClass()).IsObjectClass())) { |
| 1589 return; | 1589 return; |
| 1590 } | 1590 } |
| 1591 String& ctor_name = String::Handle(super_class.Name()); | 1591 String& ctor_name = String::Handle(super_class.Name()); |
| 1592 String& ctor_suffix = String::Handle(Symbols::Dot()); | 1592 ctor_name = String::Concat(ctor_name, Symbols::DotHandle()); |
| 1593 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
| 1594 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1593 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1595 // Implicit 'this' parameter is the first argument. | 1594 // Implicit 'this' parameter is the first argument. |
| 1596 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 1595 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 1597 arguments->Add(implicit_argument); | 1596 arguments->Add(implicit_argument); |
| 1598 // Implicit construction phase parameter is second argument. | 1597 // Implicit construction phase parameter is second argument. |
| 1599 AstNode* phase_parameter = | 1598 AstNode* phase_parameter = |
| 1600 new LiteralNode(supercall_pos, | 1599 new LiteralNode(supercall_pos, |
| 1601 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); | 1600 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
| 1602 arguments->Add(phase_parameter); | 1601 arguments->Add(phase_parameter); |
| 1603 const Function& super_ctor = Function::ZoneHandle( | 1602 const Function& super_ctor = Function::ZoneHandle( |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1623 | 1622 |
| 1624 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 1623 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 1625 LocalVariable* receiver) { | 1624 LocalVariable* receiver) { |
| 1626 TRACE_PARSER("ParseSuperInitializer"); | 1625 TRACE_PARSER("ParseSuperInitializer"); |
| 1627 ASSERT(CurrentToken() == Token::kSUPER); | 1626 ASSERT(CurrentToken() == Token::kSUPER); |
| 1628 const intptr_t supercall_pos = TokenPos(); | 1627 const intptr_t supercall_pos = TokenPos(); |
| 1629 ConsumeToken(); | 1628 ConsumeToken(); |
| 1630 const Class& super_class = Class::Handle(cls.SuperClass()); | 1629 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1631 ASSERT(!super_class.IsNull()); | 1630 ASSERT(!super_class.IsNull()); |
| 1632 String& ctor_name = String::Handle(super_class.Name()); | 1631 String& ctor_name = String::Handle(super_class.Name()); |
| 1633 String& ctor_suffix = String::Handle(Symbols::Dot()); | |
| 1634 if (CurrentToken() == Token::kPERIOD) { | 1632 if (CurrentToken() == Token::kPERIOD) { |
| 1635 ConsumeToken(); | 1633 ConsumeToken(); |
| 1636 ctor_suffix = String::Concat( | 1634 const String& ctor_suffix = String::Handle( |
|
hausner
2012/12/08 00:01:15
Looks like this could be simplified now, roughly l
siva
2012/12/08 00:13:56
Nice.
I fixed it.
On 2012/12/08 00:01:15, hausn
| |
| 1637 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1635 String::Concat(Symbols::DotHandle(), |
| 1636 *ExpectIdentifier("constructor name expected"))); | |
| 1637 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
| 1638 } else { | |
| 1639 ctor_name = String::Concat(ctor_name, Symbols::DotHandle()); | |
| 1638 } | 1640 } |
| 1639 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
| 1640 if (CurrentToken() != Token::kLPAREN) { | 1641 if (CurrentToken() != Token::kLPAREN) { |
| 1641 ErrorMsg("parameter list expected"); | 1642 ErrorMsg("parameter list expected"); |
| 1642 } | 1643 } |
| 1643 | 1644 |
| 1644 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1645 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1645 // 'this' parameter is the first argument to super class constructor. | 1646 // 'this' parameter is the first argument to super class constructor. |
| 1646 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 1647 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 1647 arguments->Add(implicit_argument); | 1648 arguments->Add(implicit_argument); |
| 1648 // Second implicit parameter is the construction phase. We optimistically | 1649 // Second implicit parameter is the construction phase. We optimistically |
| 1649 // assume that we can execute both the super initializer and the super | 1650 // assume that we can execute both the super initializer and the super |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1842 } | 1843 } |
| 1843 | 1844 |
| 1844 | 1845 |
| 1845 void Parser::ParseConstructorRedirection(const Class& cls, | 1846 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1846 LocalVariable* receiver) { | 1847 LocalVariable* receiver) { |
| 1847 TRACE_PARSER("ParseConstructorRedirection"); | 1848 TRACE_PARSER("ParseConstructorRedirection"); |
| 1848 ASSERT(CurrentToken() == Token::kTHIS); | 1849 ASSERT(CurrentToken() == Token::kTHIS); |
| 1849 const intptr_t call_pos = TokenPos(); | 1850 const intptr_t call_pos = TokenPos(); |
| 1850 ConsumeToken(); | 1851 ConsumeToken(); |
| 1851 String& ctor_name = String::Handle(cls.Name()); | 1852 String& ctor_name = String::Handle(cls.Name()); |
| 1852 String& ctor_suffix = String::Handle(Symbols::Dot()); | |
| 1853 | 1853 |
| 1854 if (CurrentToken() == Token::kPERIOD) { | 1854 if (CurrentToken() == Token::kPERIOD) { |
| 1855 ConsumeToken(); | 1855 ConsumeToken(); |
| 1856 ctor_suffix = String::Concat( | 1856 const String& ctor_suffix = String::Handle( |
|
hausner
2012/12/08 00:01:15
ditto.
siva
2012/12/08 00:13:56
Done.
| |
| 1857 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1857 String::Concat(Symbols::DotHandle(), |
| 1858 *ExpectIdentifier("constructor name expected"))); | |
| 1859 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
| 1860 } else { | |
| 1861 ctor_name = String::Concat(ctor_name, Symbols::DotHandle()); | |
| 1858 } | 1862 } |
| 1859 ctor_name = String::Concat(ctor_name, ctor_suffix); | |
| 1860 if (CurrentToken() != Token::kLPAREN) { | 1863 if (CurrentToken() != Token::kLPAREN) { |
| 1861 ErrorMsg("parameter list expected"); | 1864 ErrorMsg("parameter list expected"); |
| 1862 } | 1865 } |
| 1863 | 1866 |
| 1864 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 1867 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
| 1865 // 'this' parameter is the first argument to constructor. | 1868 // 'this' parameter is the first argument to constructor. |
| 1866 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); | 1869 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); |
| 1867 arguments->Add(implicit_argument); | 1870 arguments->Add(implicit_argument); |
| 1868 // Construction phase parameter is second argument. | 1871 // Construction phase parameter is second argument. |
| 1869 LocalVariable* phase_param = LookupPhaseParameter(); | 1872 LocalVariable* phase_param = LookupPhaseParameter(); |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2534 // Redirected constructor: either this(...) or this.xxx(...). | 2537 // Redirected constructor: either this(...) or this.xxx(...). |
| 2535 if (method->params.has_field_initializer) { | 2538 if (method->params.has_field_initializer) { |
| 2536 // Constructors that redirect to another constructor must not | 2539 // Constructors that redirect to another constructor must not |
| 2537 // initialize any fields using field initializer parameters. | 2540 // initialize any fields using field initializer parameters. |
| 2538 ErrorMsg(formal_param_pos, "Redirecting constructor " | 2541 ErrorMsg(formal_param_pos, "Redirecting constructor " |
| 2539 "may not use field initializer parameters"); | 2542 "may not use field initializer parameters"); |
| 2540 } | 2543 } |
| 2541 ConsumeToken(); // Colon. | 2544 ConsumeToken(); // Colon. |
| 2542 ExpectToken(Token::kTHIS); | 2545 ExpectToken(Token::kTHIS); |
| 2543 String& redir_name = String::ZoneHandle( | 2546 String& redir_name = String::ZoneHandle( |
| 2544 String::Concat(members->class_name(), | 2547 String::Concat(members->class_name(), Symbols::DotHandle())); |
| 2545 String::Handle(Symbols::Dot()))); | |
| 2546 if (CurrentToken() == Token::kPERIOD) { | 2548 if (CurrentToken() == Token::kPERIOD) { |
| 2547 ConsumeToken(); | 2549 ConsumeToken(); |
| 2548 redir_name = String::Concat(redir_name, | 2550 redir_name = String::Concat(redir_name, |
| 2549 *ExpectIdentifier("constructor name expected")); | 2551 *ExpectIdentifier("constructor name expected")); |
| 2550 } | 2552 } |
| 2551 method->redirect_name = &redir_name; | 2553 method->redirect_name = &redir_name; |
| 2552 if (CurrentToken() != Token::kLPAREN) { | 2554 if (CurrentToken() != Token::kLPAREN) { |
| 2553 ErrorMsg("'(' expected"); | 2555 ErrorMsg("'(' expected"); |
| 2554 } | 2556 } |
| 2555 SkipToMatchingParenthesis(); | 2557 SkipToMatchingParenthesis(); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2941 member.name_pos)); | 2943 member.name_pos)); |
| 2942 // The type arguments of the result type are set during finalization. | 2944 // The type arguments of the result type are set during finalization. |
| 2943 member.type = &Type::ZoneHandle(Type::New(result_type_class, | 2945 member.type = &Type::ZoneHandle(Type::New(result_type_class, |
| 2944 TypeArguments::Handle(), | 2946 TypeArguments::Handle(), |
| 2945 member.name_pos)); | 2947 member.name_pos)); |
| 2946 } else if (member.has_static) { | 2948 } else if (member.has_static) { |
| 2947 ErrorMsg(member.name_pos, "constructor cannot be static"); | 2949 ErrorMsg(member.name_pos, "constructor cannot be static"); |
| 2948 } | 2950 } |
| 2949 // We must be dealing with a constructor or named constructor. | 2951 // We must be dealing with a constructor or named constructor. |
| 2950 member.kind = RawFunction::kConstructor; | 2952 member.kind = RawFunction::kConstructor; |
| 2951 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); | |
| 2952 if (CurrentToken() == Token::kPERIOD) { | 2953 if (CurrentToken() == Token::kPERIOD) { |
| 2953 // Named constructor. | 2954 // Named constructor. |
| 2954 ConsumeToken(); | 2955 ConsumeToken(); |
| 2955 member.constructor_name = ExpectIdentifier("identifier expected"); | 2956 member.constructor_name = ExpectIdentifier("identifier expected"); |
| 2956 ctor_suffix = String::Concat(ctor_suffix, *member.constructor_name); | 2957 const String& ctor_suffix = String::Handle( |
|
hausner
2012/12/08 00:01:15
ditto
siva
2012/12/08 00:13:56
Done.
| |
| 2958 String::Concat(Symbols::DotHandle(), *member.constructor_name)); | |
| 2959 *member.name = String::Concat(*member.name, ctor_suffix); | |
| 2960 } else { | |
| 2961 *member.name = String::Concat(*member.name, Symbols::DotHandle()); | |
| 2957 } | 2962 } |
| 2958 *member.name = String::Concat(*member.name, ctor_suffix); | |
| 2959 // Ensure that names are symbols. | 2963 // Ensure that names are symbols. |
| 2960 *member.name = Symbols::New(*member.name); | 2964 *member.name = Symbols::New(*member.name); |
| 2961 if (member.type == NULL) { | 2965 if (member.type == NULL) { |
| 2962 ASSERT(!member.has_factory); | 2966 ASSERT(!member.has_factory); |
| 2963 // The body of the constructor cannot modify the type arguments of the | 2967 // The body of the constructor cannot modify the type arguments of the |
| 2964 // constructed instance, which is passed in as a hidden parameter. | 2968 // constructed instance, which is passed in as a hidden parameter. |
| 2965 // Therefore, there is no need to set the result type to be checked. | 2969 // Therefore, there is no need to set the result type to be checked. |
| 2966 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2970 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2967 } else { | 2971 } else { |
| 2968 // The type can only be already set in the factory case. | 2972 // The type can only be already set in the factory case. |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3181 } | 3185 } |
| 3182 } | 3186 } |
| 3183 } | 3187 } |
| 3184 | 3188 |
| 3185 | 3189 |
| 3186 // Add an implicit constructor if no explicit constructor is present. | 3190 // Add an implicit constructor if no explicit constructor is present. |
| 3187 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { | 3191 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { |
| 3188 // The implicit constructor is unnamed, has no explicit parameter, | 3192 // The implicit constructor is unnamed, has no explicit parameter, |
| 3189 // and contains a supercall in the initializer list. | 3193 // and contains a supercall in the initializer list. |
| 3190 String& ctor_name = String::ZoneHandle( | 3194 String& ctor_name = String::ZoneHandle( |
| 3191 String::Concat(class_desc->class_name(), String::Handle(Symbols::Dot()))); | 3195 String::Concat(class_desc->class_name(), Symbols::DotHandle())); |
| 3192 ctor_name = Symbols::New(ctor_name); | 3196 ctor_name = Symbols::New(ctor_name); |
| 3193 // The token position for the implicit constructor is the 'class' | 3197 // The token position for the implicit constructor is the 'class' |
| 3194 // keyword of the constructor's class. | 3198 // keyword of the constructor's class. |
| 3195 Function& ctor = Function::Handle( | 3199 Function& ctor = Function::Handle( |
| 3196 Function::New(ctor_name, | 3200 Function::New(ctor_name, |
| 3197 RawFunction::kConstructor, | 3201 RawFunction::kConstructor, |
| 3198 /* is_static = */ false, | 3202 /* is_static = */ false, |
| 3199 /* is_const = */ false, | 3203 /* is_const = */ false, |
| 3200 /* is_abstract = */ false, | 3204 /* is_abstract = */ false, |
| 3201 /* is_external = */ false, | 3205 /* is_external = */ false, |
| (...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4068 CallLibraryTagHandler(kSourceTag, source_pos, canon_url); | 4072 CallLibraryTagHandler(kSourceTag, source_pos, canon_url); |
| 4069 } | 4073 } |
| 4070 } | 4074 } |
| 4071 | 4075 |
| 4072 | 4076 |
| 4073 void Parser::ParseLibraryName() { | 4077 void Parser::ParseLibraryName() { |
| 4074 ASSERT(CurrentToken() == Token::kLIBRARY); | 4078 ASSERT(CurrentToken() == Token::kLIBRARY); |
| 4075 ConsumeToken(); | 4079 ConsumeToken(); |
| 4076 String& lib_name = *ExpectIdentifier("library name expected"); | 4080 String& lib_name = *ExpectIdentifier("library name expected"); |
| 4077 if (CurrentToken() == Token::kPERIOD) { | 4081 if (CurrentToken() == Token::kPERIOD) { |
| 4078 const String& dot = String::Handle(Symbols::Dot()); | |
| 4079 while (CurrentToken() == Token::kPERIOD) { | 4082 while (CurrentToken() == Token::kPERIOD) { |
| 4080 ConsumeToken(); | 4083 ConsumeToken(); |
| 4081 lib_name = String::Concat(lib_name, dot); | 4084 lib_name = String::Concat(lib_name, Symbols::DotHandle()); |
| 4082 lib_name = String::Concat(lib_name, | 4085 lib_name = String::Concat(lib_name, |
| 4083 *ExpectIdentifier("malformed library name")); | 4086 *ExpectIdentifier("malformed library name")); |
| 4084 } | 4087 } |
| 4085 lib_name = Symbols::New(lib_name); | 4088 lib_name = Symbols::New(lib_name); |
| 4086 } | 4089 } |
| 4087 library_.SetName(lib_name); | 4090 library_.SetName(lib_name); |
| 4088 ExpectSemicolon(); | 4091 ExpectSemicolon(); |
| 4089 } | 4092 } |
| 4090 | 4093 |
| 4091 | 4094 |
| (...skipping 4777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8869 return primary; | 8872 return primary; |
| 8870 } | 8873 } |
| 8871 | 8874 |
| 8872 | 8875 |
| 8873 static const String& BuildConstructorName(const String& type_class_name, | 8876 static const String& BuildConstructorName(const String& type_class_name, |
| 8874 const String* named_constructor) { | 8877 const String* named_constructor) { |
| 8875 // By convention, the static function implementing a named constructor 'C' | 8878 // By convention, the static function implementing a named constructor 'C' |
| 8876 // for class 'A' is labeled 'A.C', and the static function implementing the | 8879 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 8877 // unnamed constructor for class 'A' is labeled 'A.'. | 8880 // unnamed constructor for class 'A' is labeled 'A.'. |
| 8878 // This convention prevents users from explicitly calling constructors. | 8881 // This convention prevents users from explicitly calling constructors. |
| 8879 const String& period = String::Handle(Symbols::Dot()); | |
| 8880 String& constructor_name = | 8882 String& constructor_name = |
| 8881 String::Handle(String::Concat(type_class_name, period)); | 8883 String::Handle(String::Concat(type_class_name, Symbols::DotHandle())); |
| 8882 if (named_constructor != NULL) { | 8884 if (named_constructor != NULL) { |
| 8883 constructor_name = String::Concat(constructor_name, *named_constructor); | 8885 constructor_name = String::Concat(constructor_name, *named_constructor); |
| 8884 } | 8886 } |
| 8885 return constructor_name; | 8887 return constructor_name; |
| 8886 } | 8888 } |
| 8887 | 8889 |
| 8888 | 8890 |
| 8889 AstNode* Parser::ParseNewOperator() { | 8891 AstNode* Parser::ParseNewOperator() { |
| 8890 TRACE_PARSER("ParseNewOperator"); | 8892 TRACE_PARSER("ParseNewOperator"); |
| 8891 const intptr_t new_pos = TokenPos(); | 8893 const intptr_t new_pos = TokenPos(); |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9706 void Parser::SkipQualIdent() { | 9708 void Parser::SkipQualIdent() { |
| 9707 ASSERT(IsIdentifier()); | 9709 ASSERT(IsIdentifier()); |
| 9708 ConsumeToken(); | 9710 ConsumeToken(); |
| 9709 if (CurrentToken() == Token::kPERIOD) { | 9711 if (CurrentToken() == Token::kPERIOD) { |
| 9710 ConsumeToken(); // Consume the kPERIOD token. | 9712 ConsumeToken(); // Consume the kPERIOD token. |
| 9711 ExpectIdentifier("identifier expected after '.'"); | 9713 ExpectIdentifier("identifier expected after '.'"); |
| 9712 } | 9714 } |
| 9713 } | 9715 } |
| 9714 | 9716 |
| 9715 } // namespace dart | 9717 } // namespace dart |
| OLD | NEW |