| 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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 4714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4725 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4725 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
| 4726 } | 4726 } |
| 4727 } | 4727 } |
| 4728 } | 4728 } |
| 4729 | 4729 |
| 4730 | 4730 |
| 4731 void Parser::ParseEnumDefinition(const Class& cls) { | 4731 void Parser::ParseEnumDefinition(const Class& cls) { |
| 4732 TRACE_PARSER("ParseEnumDefinition"); | 4732 TRACE_PARSER("ParseEnumDefinition"); |
| 4733 INC_STAT(thread(), num_classes_parsed, 1); | 4733 INC_STAT(thread(), num_classes_parsed, 1); |
| 4734 | 4734 |
| 4735 const Class& helper_class = |
| 4736 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); |
| 4737 ASSERT(!helper_class.IsNull()); |
| 4738 |
| 4735 SkipMetadata(); | 4739 SkipMetadata(); |
| 4736 ExpectToken(Token::kENUM); | 4740 ExpectToken(Token::kENUM); |
| 4737 | 4741 |
| 4738 const String& enum_name = String::Handle(Z, cls.ScrubbedName()); | 4742 const String& enum_name = String::Handle(Z, cls.ScrubbedName()); |
| 4739 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); | 4743 ClassDesc enum_members(Z, cls, enum_name, false, cls.token_pos()); |
| 4740 | 4744 |
| 4741 // Add instance field 'final int index'. | 4745 // Add instance field 'final int index'. |
| 4742 Field& index_field = Field::ZoneHandle(Z); | 4746 Field& index_field = Field::ZoneHandle(Z); |
| 4743 const Type& int_type = Type::Handle(Z, Type::IntType()); | 4747 const Type& int_type = Type::Handle(Z, Type::IntType()); |
| 4744 index_field = Field::New(Symbols::Index(), | 4748 index_field = Field::New(Symbols::Index(), |
| 4745 false, // Not static. | 4749 false, // Not static. |
| 4746 true, // Field is final. | 4750 true, // Field is final. |
| 4747 false, // Not const. | 4751 false, // Not const. |
| 4748 true, // Is reflectable. | 4752 true, // Is reflectable. |
| 4749 cls, | 4753 cls, |
| 4750 int_type, | 4754 int_type, |
| 4751 cls.token_pos()); | 4755 cls.token_pos()); |
| 4752 enum_members.AddField(index_field); | 4756 enum_members.AddField(index_field); |
| 4753 | 4757 |
| 4754 // Add implicit getter for index field. | 4758 // Add implicit getter for index field. |
| 4755 const String& getter_name = | 4759 const String& getter_name = |
| 4756 String::Handle(Z, Field::GetterSymbol(Symbols::Index())); | 4760 String::Handle(Z, Field::GetterSymbol(Symbols::Index())); |
| 4757 Function& getter = Function::Handle(Z); | 4761 Function& getter = Function::Handle(Z); |
| 4758 getter = Function::New(getter_name, | 4762 getter = Function::New(getter_name, |
| 4759 RawFunction::kImplicitGetter, | 4763 RawFunction::kImplicitGetter, |
| 4760 /* is_static = */ false, | 4764 /* is_static = */ false, |
| 4761 /* is_const = */ true, | 4765 /* is_const = */ true, |
| 4762 /* is_abstract = */ false, | 4766 /* is_abstract = */ false, |
| 4763 /* is_external = */ false, | 4767 /* is_external = */ false, |
| 4764 /* is_native = */ false, | 4768 /* is_native = */ false, |
| 4765 cls, | 4769 cls, |
| 4766 cls.token_pos()); | 4770 cls.token_pos()); |
| 4767 getter.set_result_type(int_type); | 4771 getter.set_result_type(int_type); |
| 4768 getter.set_is_debuggable(false); | 4772 getter.set_is_debuggable(false); |
| 4769 ParamList params; | 4773 ParamList params; |
| 4770 params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); | 4774 params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); |
| 4771 AddFormalParamsToFunction(¶ms, getter); | 4775 AddFormalParamsToFunction(¶ms, getter); |
| 4772 enum_members.AddFunction(getter); | 4776 enum_members.AddFunction(getter); |
| 4773 | 4777 |
| 4774 GrowableObjectArray& enum_names = GrowableObjectArray::Handle(Z, | |
| 4775 GrowableObjectArray::New(8, Heap::kOld)); | |
| 4776 const String& name_prefix = | |
| 4777 String::Handle(String::Concat(enum_name, Symbols::Dot())); | |
| 4778 | |
| 4779 ASSERT(IsIdentifier()); | 4778 ASSERT(IsIdentifier()); |
| 4780 ASSERT(CurrentLiteral()->raw() == cls.Name()); | 4779 ASSERT(CurrentLiteral()->raw() == cls.Name()); |
| 4781 | 4780 |
| 4782 ConsumeToken(); // Enum type name. | 4781 ConsumeToken(); // Enum type name. |
| 4783 ExpectToken(Token::kLBRACE); | 4782 ExpectToken(Token::kLBRACE); |
| 4784 Field& enum_value = Field::Handle(Z); | 4783 Field& enum_value = Field::Handle(Z); |
| 4785 String& enum_value_name = String::Handle(Z); | |
| 4786 intptr_t i = 0; | 4784 intptr_t i = 0; |
| 4787 GrowableArray<String*> declared_names(8); | 4785 GrowableArray<String*> declared_names(8); |
| 4788 | 4786 |
| 4789 while (IsIdentifier()) { | 4787 while (IsIdentifier()) { |
| 4790 String* enum_ident = CurrentLiteral(); | 4788 String* enum_ident = CurrentLiteral(); |
| 4791 | 4789 |
| 4792 // Check for name conflicts. | 4790 // Check for name conflicts. |
| 4793 if (enum_ident->raw() == cls.Name()) { | 4791 if (enum_ident->raw() == cls.Name()) { |
| 4794 ReportError("enum identifier '%s' cannot be equal to enum type name", | 4792 ReportError("enum identifier '%s' cannot be equal to enum type name", |
| 4795 CurrentLiteral()->ToCString()); | 4793 CurrentLiteral()->ToCString()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4823 cls.token_pos()); | 4821 cls.token_pos()); |
| 4824 enum_value.set_has_initializer(false); | 4822 enum_value.set_has_initializer(false); |
| 4825 enum_members.AddField(enum_value); | 4823 enum_members.AddField(enum_value); |
| 4826 // Initialize the field with the ordinal value. It will be patched | 4824 // Initialize the field with the ordinal value. It will be patched |
| 4827 // later with the enum constant instance. | 4825 // later with the enum constant instance. |
| 4828 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); | 4826 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); |
| 4829 enum_value.SetStaticValue(ordinal_value, true); | 4827 enum_value.SetStaticValue(ordinal_value, true); |
| 4830 enum_value.RecordStore(ordinal_value); | 4828 enum_value.RecordStore(ordinal_value); |
| 4831 i++; | 4829 i++; |
| 4832 | 4830 |
| 4833 // For the user-visible name of the enumeration value, we need to | |
| 4834 // unmangle private names. | |
| 4835 if (enum_ident->CharAt(0) == '_') { | |
| 4836 *enum_ident = String::ScrubName(*enum_ident); | |
| 4837 } | |
| 4838 enum_value_name = Symbols::FromConcat(T, name_prefix, *enum_ident); | |
| 4839 enum_names.Add(enum_value_name, Heap::kOld); | |
| 4840 | |
| 4841 ConsumeToken(); // Enum value name. | 4831 ConsumeToken(); // Enum value name. |
| 4842 if (CurrentToken() == Token::kCOMMA) { | 4832 if (CurrentToken() == Token::kCOMMA) { |
| 4843 ConsumeToken(); | 4833 ConsumeToken(); |
| 4844 } | 4834 } |
| 4845 } | 4835 } |
| 4846 ExpectToken(Token::kRBRACE); | 4836 ExpectToken(Token::kRBRACE); |
| 4847 | 4837 |
| 4848 const Class& helper_class = | |
| 4849 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); | |
| 4850 ASSERT(!helper_class.IsNull()); | |
| 4851 | |
| 4852 // Add static field 'const List values'. | 4838 // Add static field 'const List values'. |
| 4853 Field& values_field = Field::ZoneHandle(Z); | 4839 Field& values_field = Field::ZoneHandle(Z); |
| 4854 values_field = Field::New(Symbols::Values(), | 4840 values_field = Field::New(Symbols::Values(), |
| 4855 /* is_static = */ true, | 4841 /* is_static = */ true, |
| 4856 /* is_final = */ true, | 4842 /* is_final = */ true, |
| 4857 /* is_const = */ true, | 4843 /* is_const = */ true, |
| 4858 /* is_reflectable = */ true, | 4844 /* is_reflectable = */ true, |
| 4859 cls, | 4845 cls, |
| 4860 Type::Handle(Z, Type::ArrayType()), | 4846 Type::Handle(Z, Type::ArrayType()), |
| 4861 cls.token_pos()); | 4847 cls.token_pos()); |
| 4862 enum_members.AddField(values_field); | 4848 enum_members.AddField(values_field); |
| 4863 | 4849 |
| 4864 // Allocate the immutable array containing the enumeration values. | 4850 // Allocate the immutable array containing the enumeration values. |
| 4865 // The actual enum instance values will be patched in later. | 4851 // The actual enum instance values will be patched in later. |
| 4866 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); | 4852 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); |
| 4867 values_field.SetStaticValue(values_array, true); | 4853 values_field.SetStaticValue(values_array, true); |
| 4868 values_field.RecordStore(values_array); | 4854 values_field.RecordStore(values_array); |
| 4869 | 4855 |
| 4870 // Create a static field that contains the list of enumeration names. | 4856 // Clone the _name field from the helper class. |
| 4871 // Clone the _enum_names field from the helper class. | 4857 Field& _name_field = Field::Handle(Z, |
| 4872 Field& names_field = Field::Handle(Z, | 4858 helper_class.LookupInstanceFieldAllowPrivate(Symbols::_name())); |
| 4873 helper_class.LookupStaticFieldAllowPrivate(Symbols::_EnumNames())); | 4859 ASSERT(!_name_field.IsNull()); |
| 4874 ASSERT(!names_field.IsNull()); | 4860 _name_field = _name_field.Clone(cls); |
| 4875 names_field = names_field.Clone(cls); | 4861 enum_members.AddField(_name_field); |
| 4876 enum_members.AddField(names_field); | 4862 |
| 4877 const Array& names_array = Array::Handle(Array::MakeArray(enum_names)); | 4863 // Add an implicit getter function for the _name field. We use the field's |
| 4878 names_field.SetStaticValue(names_array, true); | 4864 // name directly here so that the private key matches those of the other |
| 4879 names_field.RecordStore(names_array); | 4865 // cloned helper functions and fields. |
| 4866 const Type& string_type = Type::Handle(Z, Type::StringType()); |
| 4867 const String& name_getter_name = String::Handle(Z, |
| 4868 Field::GetterSymbol(String::Handle(_name_field.name()))); |
| 4869 Function& name_getter = Function::Handle(Z); |
| 4870 name_getter = Function::New(name_getter_name, |
| 4871 RawFunction::kImplicitGetter, |
| 4872 /* is_static = */ false, |
| 4873 /* is_const = */ true, |
| 4874 /* is_abstract = */ false, |
| 4875 /* is_external = */ false, |
| 4876 /* is_native = */ false, |
| 4877 cls, |
| 4878 cls.token_pos()); |
| 4879 name_getter.set_result_type(string_type); |
| 4880 name_getter.set_is_debuggable(false); |
| 4881 ParamList name_params; |
| 4882 name_params.AddReceiver(&Object::dynamic_type(), cls.token_pos()); |
| 4883 AddFormalParamsToFunction(&name_params, name_getter); |
| 4884 enum_members.AddFunction(name_getter); |
| 4880 | 4885 |
| 4881 // Clone the toString() function from the helper class. | 4886 // Clone the toString() function from the helper class. |
| 4882 Function& to_string_func = Function::Handle(Z, | 4887 Function& to_string_func = Function::Handle(Z, |
| 4883 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); | 4888 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); |
| 4884 ASSERT(!to_string_func.IsNull()); | 4889 ASSERT(!to_string_func.IsNull()); |
| 4885 to_string_func = to_string_func.Clone(cls); | 4890 to_string_func = to_string_func.Clone(cls); |
| 4886 enum_members.AddFunction(to_string_func); | 4891 enum_members.AddFunction(to_string_func); |
| 4887 | 4892 |
| 4888 // Clone the hashCode getter function from the helper class. | 4893 // Clone the hashCode getter function from the helper class. |
| 4889 Function& hash_code_func = Function::Handle(Z, | 4894 Function& hash_code_func = Function::Handle(Z, |
| (...skipping 9739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14629 const ArgumentListNode& function_args, | 14634 const ArgumentListNode& function_args, |
| 14630 const LocalVariable* temp_for_last_arg, | 14635 const LocalVariable* temp_for_last_arg, |
| 14631 bool is_super_invocation) { | 14636 bool is_super_invocation) { |
| 14632 UNREACHABLE(); | 14637 UNREACHABLE(); |
| 14633 return NULL; | 14638 return NULL; |
| 14634 } | 14639 } |
| 14635 | 14640 |
| 14636 } // namespace dart | 14641 } // namespace dart |
| 14637 | 14642 |
| 14638 #endif // DART_PRECOMPILED_RUNTIME | 14643 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |