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 |