| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 from collections import namedtuple | |
| 7 import math | 6 import math |
| 8 import sys | 7 import sys |
| 9 | 8 |
| 10 import in_generator | 9 import in_generator |
| 11 import template_expander | 10 import template_expander |
| 12 import make_style_builder | 11 import make_style_builder |
| 13 | 12 |
| 14 from name_utilities import camel_case | 13 from name_utilities import camel_case |
| 15 | 14 |
| 15 |
| 16 class Field(object): |
| 17 """ |
| 18 The generated ComputedStyle object is made up of a series of Fields. |
| 19 Each Field has a name, size, type, etc, and a bunch of attributes to |
| 20 determine which methods it will be used in. |
| 21 |
| 22 A Field also has enough information to use any storage type in C++, such as |
| 23 regular member variables, or more complex storage like vectors or hashmaps. |
| 24 Almost all properties will have at least one Field, often more than one. |
| 25 |
| 26 Fields also fall into various families, which determine the logic that is |
| 27 used to generate them. The available field families are: |
| 28 - 'enum', for fields that store the values of an enum |
| 29 - 'inherited_flag', for single-bit flags that store whether a property is |
| 30 inherited by this style or set explicitly |
| 31 """ |
| 32 def __init__(self, field_family, **kwargs): |
| 33 # Values common to all fields |
| 34 # Name of field |
| 35 self.name = kwargs.pop('name') |
| 36 # Property field is for |
| 37 self.property = kwargs.pop('property') |
| 38 # Field storage type |
| 39 self.type = kwargs.pop('type') |
| 40 # Bits needed for storage |
| 41 self.size = kwargs.pop('size') |
| 42 # Default value for field |
| 43 self.default_value = kwargs.pop('default_value') |
| 44 # Method names |
| 45 self.getter_method_name = kwargs.pop('getter_method_name') |
| 46 self.setter_method_name = kwargs.pop('setter_method_name') |
| 47 self.initial_method_name = kwargs.pop('initial_method_name') |
| 48 self.resetter_method_name = kwargs.pop('resetter_method_name') |
| 49 |
| 50 # Field family: one of these must be true |
| 51 self.is_enum = field_family == 'enum' |
| 52 self.is_inherited_flag = field_family == 'inherited_flag' |
| 53 assert not (self.is_enum and self.is_inherited_flag), 'Only one field fa
mily can be specified at a time' |
| 54 |
| 55 if self.is_enum: |
| 56 # Enum-only fields |
| 57 self.is_inherited_method_name = kwargs.pop('is_inherited_method_name
') |
| 58 elif self.is_inherited_flag: |
| 59 # Inherited flag-only fields |
| 60 pass |
| 61 |
| 62 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st
r(kwargs) |
| 63 |
| 64 |
| 16 class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter): | 65 class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter): |
| 17 def __init__(self, in_file_path): | 66 def __init__(self, in_file_path): |
| 18 super(ComputedStyleBaseWriter, self).__init__(in_file_path) | 67 super(ComputedStyleBaseWriter, self).__init__(in_file_path) |
| 19 self._outputs = { | 68 self._outputs = { |
| 20 'ComputedStyleBase.h': self.generate_base_computed_style_h, | 69 'ComputedStyleBase.h': self.generate_base_computed_style_h, |
| 21 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, | 70 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, |
| 22 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co
nstants, | 71 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co
nstants, |
| 23 } | 72 } |
| 24 | 73 |
| 25 # A map of enum name -> list of enum values | 74 # A map of enum name -> list of enum values |
| 26 self._computed_enums = {} | 75 self._computed_enums = {} |
| 27 for property in self._properties.values(): | 76 for property in self._properties.values(): |
| 28 if property['keyword_only']: | 77 if property['keyword_only']: |
| 29 enum_name = property['type_name'] | 78 enum_name = property['type_name'] |
| 30 # From the Blink style guide: Enum members should use InterCaps
with an initial capital letter. [names-enum-members] | 79 # From the Blink style guide: Enum members should use InterCaps
with an initial capital letter. [names-enum-members] |
| 31 enum_values = [camel_case(k) for k in property['keywords']] | 80 enum_values = [camel_case(k) for k in property['keywords']] |
| 32 self._computed_enums[enum_name] = enum_values | 81 self._computed_enums[enum_name] = enum_values |
| 33 | 82 |
| 34 # A list of fields for the generated class. | 83 # A list of all the fields to be generated. |
| 35 # TODO(sashab): Rename this to Member, and add better documentation for
what this list is for, | |
| 36 # including asserts to show inter-field dependencies. | |
| 37 Field = namedtuple('Field', [ | |
| 38 # Name of field member variable | |
| 39 'name', | |
| 40 # Property field is for | |
| 41 'property', | |
| 42 # Field family: one of these must be true | |
| 43 'is_enum', | |
| 44 'is_inherited_flag', | |
| 45 # Field storage type | |
| 46 'type', | |
| 47 # Bits needed for storage | |
| 48 'size', | |
| 49 # Default value for field | |
| 50 'default_value', | |
| 51 # Method names | |
| 52 'getter_method_name', | |
| 53 'setter_method_name', | |
| 54 'initial_method_name', | |
| 55 'resetter_method_name', | |
| 56 'is_inherited_method_name', | |
| 57 ]) | |
| 58 | |
| 59 # A list of all the fields to be generated. Add new fields here. | |
| 60 self._fields = [] | 84 self._fields = [] |
| 61 for property in self._properties.values(): | 85 for property in self._properties.values(): |
| 62 if property['keyword_only']: | 86 if property['keyword_only']: |
| 63 property_name = property['upper_camel_name'] | 87 property_name = property['upper_camel_name'] |
| 64 if property['name_for_methods']: | 88 if property['name_for_methods']: |
| 65 property_name = property['name_for_methods'] | 89 property_name = property['name_for_methods'] |
| 66 property_name_lower = property_name[0].lower() + property_name[1
:] | 90 property_name_lower = property_name[0].lower() + property_name[1
:] |
| 67 | 91 |
| 68 # From the Blink style guide: Other data members should be prefi
xed by "m_". [names-data-members] | 92 # From the Blink style guide: Other data members should be prefi
xed by "m_". [names-data-members] |
| 69 field_name = 'm_' + property_name_lower | 93 field_name = 'm_' + property_name_lower |
| 70 bits_needed = math.log(len(property['keywords']), 2) | 94 bits_needed = math.log(len(property['keywords']), 2) |
| 71 type_name = property['type_name'] | 95 type_name = property['type_name'] |
| 72 | 96 |
| 73 assert property['initial_keyword'] is not None, \ | 97 assert property['initial_keyword'] is not None, \ |
| 74 ('MakeComputedStyleBase requires an initial keyword for keyw
ord_only values, none specified ' | 98 ('MakeComputedStyleBase requires an initial keyword for keyw
ord_only values, none specified ' |
| 75 'for property ' + property['name']) | 99 'for property ' + property['name']) |
| 76 default_value = type_name + '::' + camel_case(property['initial_
keyword']) | 100 default_value = type_name + '::' + camel_case(property['initial_
keyword']) |
| 77 | 101 |
| 78 # If the property is independent, add the single-bit sized isInh
erited flag | 102 # If the property is independent, add the single-bit sized isInh
erited flag |
| 79 # to the list of member variable as well. | 103 # to the list of Fields as well. |
| 80 if property['independent']: | 104 if property['independent']: |
| 81 field_name_suffix_upper = property['upper_camel_name'] + 'Is
Inherited' | 105 field_name_suffix_upper = property['upper_camel_name'] + 'Is
Inherited' |
| 82 field_name_suffix_lower = property_name_lower + 'IsInherited
' | 106 field_name_suffix_lower = property_name_lower + 'IsInherited
' |
| 83 self._fields.append(Field( | 107 self._fields.append(Field( |
| 108 'inherited_flag', |
| 84 name='m_' + field_name_suffix_lower, | 109 name='m_' + field_name_suffix_lower, |
| 85 property=property, | 110 property=property, |
| 86 is_enum=False, | |
| 87 is_inherited_flag=True, | |
| 88 type='bool', | 111 type='bool', |
| 89 size=1, | 112 size=1, |
| 90 default_value='true', | 113 default_value='true', |
| 91 getter_method_name=field_name_suffix_lower, | 114 getter_method_name=field_name_suffix_lower, |
| 92 setter_method_name='set' + field_name_suffix_upper, | 115 setter_method_name='set' + field_name_suffix_upper, |
| 93 initial_method_name='initial' + field_name_suffix_upper, | 116 initial_method_name='initial' + field_name_suffix_upper, |
| 94 resetter_method_name='reset' + field_name_suffix_upper, | 117 resetter_method_name='reset' + field_name_suffix_upper, |
| 95 is_inherited_method_name='', | |
| 96 )) | 118 )) |
| 97 | 119 |
| 98 # Add the property itself as a member variable. | 120 # Add the property itself as a member variable. |
| 99 self._fields.append(Field( | 121 self._fields.append(Field( |
| 122 'enum', |
| 100 name=field_name, | 123 name=field_name, |
| 101 property=property, | 124 property=property, |
| 102 is_enum=True, | |
| 103 is_inherited_flag=False, | |
| 104 type=type_name, | 125 type=type_name, |
| 105 size=int(math.ceil(bits_needed)), | 126 size=int(math.ceil(bits_needed)), |
| 106 default_value=default_value, | 127 default_value=default_value, |
| 107 getter_method_name=property_name_lower, | 128 getter_method_name=property_name_lower, |
| 108 setter_method_name='set' + property_name, | 129 setter_method_name='set' + property_name, |
| 109 initial_method_name='initial' + property_name, | 130 initial_method_name='initial' + property_name, |
| 110 resetter_method_name='reset' + property_name, | 131 resetter_method_name='reset' + property_name, |
| 111 is_inherited_method_name=property_name_lower + 'IsInherited'
, | 132 is_inherited_method_name=property_name_lower + 'IsInherited'
, |
| 112 )) | 133 )) |
| 113 | 134 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 130 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 151 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
| 131 def generate_base_computed_style_constants(self): | 152 def generate_base_computed_style_constants(self): |
| 132 return { | 153 return { |
| 133 'properties': self._properties, | 154 'properties': self._properties, |
| 134 'enums': self._computed_enums, | 155 'enums': self._computed_enums, |
| 135 'fields': self._fields, | 156 'fields': self._fields, |
| 136 } | 157 } |
| 137 | 158 |
| 138 if __name__ == '__main__': | 159 if __name__ == '__main__': |
| 139 in_generator.Maker(ComputedStyleBaseWriter).main(sys.argv) | 160 in_generator.Maker(ComputedStyleBaseWriter).main(sys.argv) |
| OLD | NEW |