| 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" |
| 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 #include "vm/symbols.h" | 21 #include "vm/symbols.h" |
| 22 | 22 |
| 23 namespace dart { | 23 namespace dart { |
| 24 | 24 |
| 25 DEFINE_FLAG(bool, constructor_name_check, false, |
| 26 "Named constructors may not clash with other members"); |
| 25 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 27 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 26 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 28 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 27 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 29 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 28 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 30 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
| 29 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | 31 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
| 30 DEFINE_FLAG(bool, warn_legacy_map_literal, false, | 32 DEFINE_FLAG(bool, warn_legacy_map_literal, false, |
| 31 "Warning on legacy map literal syntax (single type argument)"); | 33 "Warning on legacy map literal syntax (single type argument)"); |
| 32 | 34 |
| 33 static void CheckedModeHandler(bool value) { | 35 static void CheckedModeHandler(bool value) { |
| 34 FLAG_enable_asserts = value; | 36 FLAG_enable_asserts = value; |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 has_final = false; | 475 has_final = false; |
| 474 has_const = false; | 476 has_const = false; |
| 475 has_static = false; | 477 has_static = false; |
| 476 has_var = false; | 478 has_var = false; |
| 477 has_factory = false; | 479 has_factory = false; |
| 478 has_operator = false; | 480 has_operator = false; |
| 479 type = NULL; | 481 type = NULL; |
| 480 name_pos = 0; | 482 name_pos = 0; |
| 481 name = NULL; | 483 name = NULL; |
| 482 redirect_name = NULL; | 484 redirect_name = NULL; |
| 485 constructor_name = NULL; |
| 483 params.Clear(); | 486 params.Clear(); |
| 484 kind = RawFunction::kRegularFunction; | 487 kind = RawFunction::kRegularFunction; |
| 485 } | 488 } |
| 486 bool IsConstructor() const { | 489 bool IsConstructor() const { |
| 487 return (kind == RawFunction::kConstructor) && !has_static; | 490 return (kind == RawFunction::kConstructor) && !has_static; |
| 488 } | 491 } |
| 489 bool IsFactory() const { | 492 bool IsFactory() const { |
| 490 return (kind == RawFunction::kConstructor) && has_static; | 493 return (kind == RawFunction::kConstructor) && has_static; |
| 491 } | 494 } |
| 492 bool IsFactoryOrConstructor() const { | 495 bool IsFactoryOrConstructor() const { |
| 493 return (kind == RawFunction::kConstructor); | 496 return (kind == RawFunction::kConstructor); |
| 494 } | 497 } |
| 495 bool IsGetter() const { | 498 bool IsGetter() const { |
| 496 return kind == RawFunction::kGetterFunction; | 499 return kind == RawFunction::kGetterFunction; |
| 497 } | 500 } |
| 498 bool IsSetter() const { | 501 bool IsSetter() const { |
| 499 return kind == RawFunction::kSetterFunction; | 502 return kind == RawFunction::kSetterFunction; |
| 500 } | 503 } |
| 501 bool has_abstract; | 504 bool has_abstract; |
| 502 bool has_external; | 505 bool has_external; |
| 503 bool has_final; | 506 bool has_final; |
| 504 bool has_const; | 507 bool has_const; |
| 505 bool has_static; | 508 bool has_static; |
| 506 bool has_var; | 509 bool has_var; |
| 507 bool has_factory; | 510 bool has_factory; |
| 508 bool has_operator; | 511 bool has_operator; |
| 509 const AbstractType* type; | 512 const AbstractType* type; |
| 510 intptr_t name_pos; | 513 intptr_t name_pos; |
| 511 String* name; | 514 String* name; |
| 512 String* redirect_name; // For constructors: NULL or redirected constructor. | 515 // For constructors: NULL or redirected constructor. |
| 516 String* redirect_name; |
| 517 // For constructors: NULL for unnamed constructor, |
| 518 // identifier after classname for named constructors. |
| 519 String* constructor_name; |
| 513 ParamList params; | 520 ParamList params; |
| 514 RawFunction::Kind kind; | 521 RawFunction::Kind kind; |
| 515 }; | 522 }; |
| 516 | 523 |
| 517 | 524 |
| 518 class ClassDesc : public ValueObject { | 525 class ClassDesc : public ValueObject { |
| 519 public: | 526 public: |
| 520 ClassDesc(const Class& cls, | 527 ClassDesc(const Class& cls, |
| 521 const String& cls_name, | 528 const String& cls_name, |
| 522 bool is_interface, | 529 bool is_interface, |
| (...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 ASSERT(!func.IsFactory()); | 1869 ASSERT(!func.IsFactory()); |
| 1863 ASSERT(!func.is_static()); | 1870 ASSERT(!func.is_static()); |
| 1864 ASSERT(!func.IsLocalFunction()); | 1871 ASSERT(!func.IsLocalFunction()); |
| 1865 const Class& cls = Class::Handle(func.Owner()); | 1872 const Class& cls = Class::Handle(func.Owner()); |
| 1866 ASSERT(!cls.IsNull()); | 1873 ASSERT(!cls.IsNull()); |
| 1867 | 1874 |
| 1868 if (CurrentToken() == Token::kCLASS) { | 1875 if (CurrentToken() == Token::kCLASS) { |
| 1869 // Special case: implicit constructor. | 1876 // Special case: implicit constructor. |
| 1870 // The parser adds an implicit default constructor when a class | 1877 // The parser adds an implicit default constructor when a class |
| 1871 // does not have any explicit constructor or factory (see | 1878 // does not have any explicit constructor or factory (see |
| 1872 // Parser::CheckConstructors). The token position of this implicit | 1879 // Parser::AddImplicitConstructor). The token position of this implicit |
| 1873 // constructor points to the 'class' keyword, which is followed | 1880 // constructor points to the 'class' keyword, which is followed |
| 1874 // by the name of the class (which is also the constructor name). | 1881 // by the name of the class (which is also the constructor name). |
| 1875 // There is no source text to parse. We just build the | 1882 // There is no source text to parse. We just build the |
| 1876 // sequence node by hand. | 1883 // sequence node by hand. |
| 1877 return MakeImplicitConstructor(func); | 1884 return MakeImplicitConstructor(func); |
| 1878 } | 1885 } |
| 1879 | 1886 |
| 1880 OpenFunctionBlock(func); | 1887 OpenFunctionBlock(func); |
| 1881 ParamList params; | 1888 ParamList params; |
| 1882 const bool allow_explicit_default_values = true; | 1889 const bool allow_explicit_default_values = true; |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2858 member.name_pos = TokenPos(); | 2865 member.name_pos = TokenPos(); |
| 2859 member.name = CurrentLiteral(); | 2866 member.name = CurrentLiteral(); |
| 2860 ConsumeToken(); | 2867 ConsumeToken(); |
| 2861 } | 2868 } |
| 2862 // We must be dealing with a constructor or named constructor. | 2869 // We must be dealing with a constructor or named constructor. |
| 2863 member.kind = RawFunction::kConstructor; | 2870 member.kind = RawFunction::kConstructor; |
| 2864 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); | 2871 String& ctor_suffix = String::ZoneHandle(Symbols::Dot()); |
| 2865 if (CurrentToken() == Token::kPERIOD) { | 2872 if (CurrentToken() == Token::kPERIOD) { |
| 2866 // Named constructor. | 2873 // Named constructor. |
| 2867 ConsumeToken(); | 2874 ConsumeToken(); |
| 2868 const String* name = ExpectIdentifier("identifier expected"); | 2875 member.constructor_name = ExpectIdentifier("identifier expected"); |
| 2869 ctor_suffix = String::Concat(ctor_suffix, *name); | 2876 ctor_suffix = String::Concat(ctor_suffix, *member.constructor_name); |
| 2870 } | 2877 } |
| 2871 *member.name = String::Concat(*member.name, ctor_suffix); | 2878 *member.name = String::Concat(*member.name, ctor_suffix); |
| 2872 // Ensure that names are symbols. | 2879 // Ensure that names are symbols. |
| 2873 *member.name = Symbols::New(*member.name); | 2880 *member.name = Symbols::New(*member.name); |
| 2874 if (member.type == NULL) { | 2881 if (member.type == NULL) { |
| 2875 ASSERT(!member.has_factory); | 2882 ASSERT(!member.has_factory); |
| 2876 // The body of the constructor cannot modify the type arguments of the | 2883 // The body of the constructor cannot modify the type arguments of the |
| 2877 // constructed instance, which is passed in as a hidden parameter. | 2884 // constructed instance, which is passed in as a hidden parameter. |
| 2878 // Therefore, there is no need to set the result type to be checked. | 2885 // Therefore, there is no need to set the result type to be checked. |
| 2879 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2886 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3088 | 3095 |
| 3089 if (is_abstract || members.is_abstract()) { | 3096 if (is_abstract || members.is_abstract()) { |
| 3090 cls.set_is_abstract(); | 3097 cls.set_is_abstract(); |
| 3091 } | 3098 } |
| 3092 | 3099 |
| 3093 // Add an implicit constructor if no explicit constructor is present. No | 3100 // Add an implicit constructor if no explicit constructor is present. No |
| 3094 // implicit constructors are needed for patch classes. | 3101 // implicit constructors are needed for patch classes. |
| 3095 if (!members.has_constructor() && !is_patch) { | 3102 if (!members.has_constructor() && !is_patch) { |
| 3096 AddImplicitConstructor(&members); | 3103 AddImplicitConstructor(&members); |
| 3097 } | 3104 } |
| 3098 CheckConstructorCycles(&members); | 3105 CheckConstructors(&members); |
| 3099 | 3106 |
| 3100 Array& array = Array::Handle(); | 3107 Array& array = Array::Handle(); |
| 3101 array = Array::MakeArray(members.fields()); | 3108 array = Array::MakeArray(members.fields()); |
| 3102 cls.SetFields(array); | 3109 cls.SetFields(array); |
| 3103 | 3110 |
| 3104 // Creating a new array for functions marks the class as parsed. | 3111 // Creating a new array for functions marks the class as parsed. |
| 3105 array = Array::MakeArray(members.functions()); | 3112 array = Array::MakeArray(members.functions()); |
| 3106 cls.SetFunctions(array); | 3113 cls.SetFunctions(array); |
| 3107 | 3114 |
| 3108 if (!is_patch) { | 3115 if (!is_patch) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 &Type::ZoneHandle(Type::SmiType())); | 3153 &Type::ZoneHandle(Type::SmiType())); |
| 3147 | 3154 |
| 3148 AddFormalParamsToFunction(¶ms, ctor); | 3155 AddFormalParamsToFunction(¶ms, ctor); |
| 3149 // The body of the constructor cannot modify the type of the constructed | 3156 // The body of the constructor cannot modify the type of the constructed |
| 3150 // instance, which is passed in as the receiver. | 3157 // instance, which is passed in as the receiver. |
| 3151 ctor.set_result_type(*((*params.parameters)[0].type)); | 3158 ctor.set_result_type(*((*params.parameters)[0].type)); |
| 3152 class_desc->AddFunction(ctor); | 3159 class_desc->AddFunction(ctor); |
| 3153 } | 3160 } |
| 3154 | 3161 |
| 3155 | 3162 |
| 3156 // Check for cycles in constructor redirection. | 3163 // Check for cycles in constructor redirection. Also check whether a |
| 3157 void Parser::CheckConstructorCycles(ClassDesc* class_desc) { | 3164 // named constructor collides with the name of another class member. |
| 3165 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 3158 // Check for cycles in constructor redirection. | 3166 // Check for cycles in constructor redirection. |
| 3159 const GrowableArray<MemberDesc>& members = class_desc->members(); | 3167 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 3160 for (int i = 0; i < members.length(); i++) { | 3168 for (int i = 0; i < members.length(); i++) { |
| 3161 MemberDesc* member = &members[i]; | 3169 MemberDesc* member = &members[i]; |
| 3170 |
| 3171 if (FLAG_constructor_name_check && member->constructor_name != NULL) { |
| 3172 if (class_desc->FunctionNameExists( |
| 3173 *member->constructor_name, member->kind)) { |
| 3174 ErrorMsg(member->name_pos, |
| 3175 "Named constructor '%s' conflicts with method or field '%s'", |
| 3176 member->name->ToCString(), |
| 3177 member->constructor_name->ToCString()); |
| 3178 } |
| 3179 } |
| 3180 |
| 3162 GrowableArray<MemberDesc*> ctors; | 3181 GrowableArray<MemberDesc*> ctors; |
| 3163 while ((member != NULL) && (member->redirect_name != NULL)) { | 3182 while ((member != NULL) && (member->redirect_name != NULL)) { |
| 3164 ASSERT(member->IsConstructor()); | 3183 ASSERT(member->IsConstructor()); |
| 3165 // Check whether we have already seen this member. | 3184 // Check whether we have already seen this member. |
| 3166 for (int i = 0; i < ctors.length(); i++) { | 3185 for (int i = 0; i < ctors.length(); i++) { |
| 3167 if (ctors[i] == member) { | 3186 if (ctors[i] == member) { |
| 3168 ErrorMsg(member->name_pos, | 3187 ErrorMsg(member->name_pos, |
| 3169 "cyclic reference in constructor redirection"); | 3188 "cyclic reference in constructor redirection"); |
| 3170 } | 3189 } |
| 3171 } | 3190 } |
| (...skipping 6213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9385 void Parser::SkipQualIdent() { | 9404 void Parser::SkipQualIdent() { |
| 9386 ASSERT(IsIdentifier()); | 9405 ASSERT(IsIdentifier()); |
| 9387 ConsumeToken(); | 9406 ConsumeToken(); |
| 9388 if (CurrentToken() == Token::kPERIOD) { | 9407 if (CurrentToken() == Token::kPERIOD) { |
| 9389 ConsumeToken(); // Consume the kPERIOD token. | 9408 ConsumeToken(); // Consume the kPERIOD token. |
| 9390 ExpectIdentifier("identifier expected after '.'"); | 9409 ExpectIdentifier("identifier expected after '.'"); |
| 9391 } | 9410 } |
| 9392 } | 9411 } |
| 9393 | 9412 |
| 9394 } // namespace dart | 9413 } // namespace dart |
| OLD | NEW |