Chromium Code Reviews| 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 self.is_enum or self.is_inherited_flag, 'Only one field family ca n be specified at a time' | |
|
meade_UTC10
2016/12/06 03:03:36
don't you want
assert !(self.is_enum and self.is_
sashab
2016/12/06 03:05:53
Oh nice lol :) Whoops
| |
| 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 | |
|
meade_UTC10
2016/12/06 03:03:36
I assume there will be something here eventually?
sashab
2016/12/06 03:05:54
Yup, think its ok if I leave it there for now just
| |
| 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 |