Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: runtime/vm/parser.cc

Issue 2153143002: Rework how enums are implemented and reloaded (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/object_reload.cc ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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(&params, getter); 4775 AddFormalParamsToFunction(&params, 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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/object_reload.cc ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698