| 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 import math | 6 import math |
| 7 import sys | 7 import sys |
| 8 | 8 |
| 9 import json5_generator | 9 import json5_generator |
| 10 import template_expander | 10 import template_expander |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 Almost all properties will have at least one Field, often more than one. | 69 Almost all properties will have at least one Field, often more than one. |
| 70 | 70 |
| 71 Most attributes in this class correspond to parameters in CSSProperties.json
5. | 71 Most attributes in this class correspond to parameters in CSSProperties.json
5. |
| 72 See that file for a more detailed explanation of each attribute. | 72 See that file for a more detailed explanation of each attribute. |
| 73 | 73 |
| 74 Attributes: | 74 Attributes: |
| 75 field_role: The semantic role of the field. Can be: | 75 field_role: The semantic role of the field. Can be: |
| 76 - 'property': for fields that store CSS properties | 76 - 'property': for fields that store CSS properties |
| 77 - 'inherited_flag': for single-bit flags that store whether a proper
ty is | 77 - 'inherited_flag': for single-bit flags that store whether a proper
ty is |
| 78 inherited by this style or set explicitly | 78 inherited by this style or set explicitly |
| 79 - 'nonproperty': for fields that are not CSS properties | |
| 80 name_for_methods: String used to form the names of getters and setters. | 79 name_for_methods: String used to form the names of getters and setters. |
| 81 Should be in upper camel case. | 80 Should be in upper camel case. |
| 82 property_name: Name of the property that the field is part of. | 81 property_name: Name of the property that the field is part of. |
| 83 type_name: Name of the C++ type exposed by the generated interface (e.g.
EClear, int). | 82 type_name: Name of the C++ type exposed by the generated interface (e.g.
EClear, int). |
| 84 field_template: Determines the interface generated for the field. Can be
one of: | 83 field_template: Determines the interface generated for the field. Can be
one of: |
| 85 keyword, flag, or monotonic_flag. | 84 keyword, flag, or monotonic_flag. |
| 86 field_group: The name of the group that this field is inside. | 85 field_group: The name of the group that this field is inside. |
| 87 size: Number of bits needed for storage. | 86 size: Number of bits needed for storage. |
| 88 default_value: Default value for this field when it is first initialized
. | 87 default_value: Default value for this field when it is first initialized
. |
| 89 """ | 88 """ |
| 90 | 89 |
| 91 def __init__(self, field_role, name_for_methods, property_name, type_name, | 90 def __init__(self, field_role, name_for_methods, property_name, type_name, |
| 92 field_template, field_group, size, default_value, | 91 field_template, field_group, size, default_value, has_custom_co
mpare_and_copy, |
| 93 getter_method_name, setter_method_name, initial_method_name, **
kwargs): | 92 getter_method_name, setter_method_name, initial_method_name, **
kwargs): |
| 94 """Creates a new field.""" | 93 """Creates a new field.""" |
| 95 self.name = class_member_name(name_for_methods) | 94 self.name = class_member_name(name_for_methods) |
| 96 self.property_name = property_name | 95 self.property_name = property_name |
| 97 self.type_name = type_name | 96 self.type_name = type_name |
| 98 self.field_template = field_template | 97 self.field_template = field_template |
| 99 self.group_name = field_group | 98 self.group_name = field_group |
| 100 self.group_member_name = class_member_name(join_name(field_group, 'data'
)) if field_group else None | 99 self.group_member_name = class_member_name(join_name(field_group, 'data'
)) if field_group else None |
| 101 self.size = size | 100 self.size = size |
| 102 self.default_value = default_value | 101 self.default_value = default_value |
| 102 self.has_custom_compare_and_copy = has_custom_compare_and_copy |
| 103 | 103 |
| 104 # Field role: one of these must be true | 104 # Field role: one of these must be true |
| 105 self.is_property = field_role == 'property' | 105 self.is_property = field_role == 'property' |
| 106 self.is_inherited_flag = field_role == 'inherited_flag' | 106 self.is_inherited_flag = field_role == 'inherited_flag' |
| 107 self.is_nonproperty = field_role == 'nonproperty' | 107 assert (self.is_property, self.is_inherited_flag).count(True) == 1, \ |
| 108 assert (self.is_property, self.is_inherited_flag, self.is_nonproperty).c
ount(True) == 1, \ | 108 'Field role has to be exactly one of: property, inherited_flag' |
| 109 'Field role has to be exactly one of: property, inherited_flag, nonp
roperty' | |
| 110 | 109 |
| 111 if not self.is_inherited_flag: | 110 if not self.is_inherited_flag: |
| 112 self.is_inherited = kwargs.pop('inherited') | 111 self.is_inherited = kwargs.pop('inherited') |
| 113 self.is_independent = kwargs.pop('independent') | 112 self.is_independent = kwargs.pop('independent') |
| 114 assert self.is_inherited or not self.is_independent, 'Only inherited
fields can be independent' | 113 assert self.is_inherited or not self.is_independent, 'Only inherited
fields can be independent' |
| 115 | 114 |
| 116 self.is_inherited_method_name = method_name(join_name(name_for_metho
ds, 'is inherited')) | 115 self.is_inherited_method_name = method_name(join_name(name_for_metho
ds, 'is inherited')) |
| 117 | 116 |
| 118 # Method names | 117 # Method names |
| 119 # TODO(nainar): Method name generation is inconsistent. Fix. | 118 # TODO(nainar): Method name generation is inconsistent. Fix. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 ("'" + property_['name'] + "' can't have type_name '" + enum
_name + "' " | 169 ("'" + property_['name'] + "' can't have type_name '" + enum
_name + "' " |
| 171 "because it was used by a previous property, but with a dif
ferent set of keywords. " | 170 "because it was used by a previous property, but with a dif
ferent set of keywords. " |
| 172 "Either give it a different name or ensure the keywords are
the same.") | 171 "Either give it a different name or ensure the keywords are
the same.") |
| 173 | 172 |
| 174 enums[enum_name] = enum_values | 173 enums[enum_name] = enum_values |
| 175 | 174 |
| 176 # Return the enums sorted by key (enum name) | 175 # Return the enums sorted by key (enum name) |
| 177 return OrderedDict(sorted(enums.items(), key=lambda t: t[0])) | 176 return OrderedDict(sorted(enums.items(), key=lambda t: t[0])) |
| 178 | 177 |
| 179 | 178 |
| 180 def _create_field(field_role, property_): | 179 def _create_property_field(property_): |
| 181 """ | 180 """ |
| 182 Create a property or nonproperty field. | 181 Create a property field. |
| 183 """ | 182 """ |
| 184 assert field_role in ('property', 'nonproperty') | |
| 185 | |
| 186 name_for_methods = property_['name_for_methods'] | 183 name_for_methods = property_['name_for_methods'] |
| 187 | 184 |
| 188 assert property_['default_value'] is not None, \ | 185 assert property_['default_value'] is not None, \ |
| 189 ('MakeComputedStyleBase requires an default value for all fields, none s
pecified ' | 186 ('MakeComputedStyleBase requires an default value for all fields, none s
pecified ' |
| 190 'for property ' + property_['name']) | 187 'for property ' + property_['name']) |
| 191 | 188 |
| 192 if property_['field_template'] == 'keyword': | 189 if property_['field_template'] == 'keyword': |
| 193 type_name = property_['type_name'] | 190 type_name = property_['type_name'] |
| 194 default_value = type_name + '::' + enum_value_name(property_['default_va
lue']) | 191 default_value = type_name + '::' + enum_value_name(property_['default_va
lue']) |
| 195 size = int(math.ceil(math.log(len(property_['keywords']), 2))) | 192 size = int(math.ceil(math.log(len(property_['keywords']), 2))) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 206 type_name = property_['type_name'] | 203 type_name = property_['type_name'] |
| 207 default_value = property_['default_value'] | 204 default_value = property_['default_value'] |
| 208 size = 1 if type_name == 'bool' else None # pack bools with 1 bit. | 205 size = 1 if type_name == 'bool' else None # pack bools with 1 bit. |
| 209 else: | 206 else: |
| 210 assert property_['field_template'] in ('monotonic_flag',) | 207 assert property_['field_template'] in ('monotonic_flag',) |
| 211 type_name = 'bool' | 208 type_name = 'bool' |
| 212 default_value = 'false' | 209 default_value = 'false' |
| 213 size = 1 | 210 size = 1 |
| 214 | 211 |
| 215 return Field( | 212 return Field( |
| 216 field_role, | 213 'property', |
| 217 name_for_methods, | 214 name_for_methods, |
| 218 property_name=property_['name'], | 215 property_name=property_['name'], |
| 219 inherited=property_['inherited'], | 216 inherited=property_['inherited'], |
| 220 independent=property_['independent'], | 217 independent=property_['independent'], |
| 221 type_name=type_name, | 218 type_name=type_name, |
| 222 field_template=property_['field_template'], | 219 field_template=property_['field_template'], |
| 223 field_group=property_['field_group'], | 220 field_group=property_['field_group'], |
| 224 size=size, | 221 size=size, |
| 225 default_value=default_value, | 222 default_value=default_value, |
| 223 has_custom_compare_and_copy=property_['has_custom_compare_and_copy'], |
| 226 getter_method_name=property_['getter'], | 224 getter_method_name=property_['getter'], |
| 227 setter_method_name=property_['setter'], | 225 setter_method_name=property_['setter'], |
| 228 initial_method_name=property_['initial'], | 226 initial_method_name=property_['initial'], |
| 229 ) | 227 ) |
| 230 | 228 |
| 231 | 229 |
| 232 def _create_inherited_flag_field(property_): | 230 def _create_inherited_flag_field(property_): |
| 233 """ | 231 """ |
| 234 Create the field used for an inheritance fast path from an independent CSS p
roperty, | 232 Create the field used for an inheritance fast path from an independent CSS p
roperty, |
| 235 and return the Field object. | 233 and return the Field object. |
| 236 """ | 234 """ |
| 237 name_for_methods = join_name(property_['name_for_methods'], 'is inherited') | 235 name_for_methods = join_name(property_['name_for_methods'], 'is inherited') |
| 238 return Field( | 236 return Field( |
| 239 'inherited_flag', | 237 'inherited_flag', |
| 240 name_for_methods, | 238 name_for_methods, |
| 241 property_name=property_['name'], | 239 property_name=property_['name'], |
| 242 type_name='bool', | 240 type_name='bool', |
| 243 field_template='primitive', | 241 field_template='primitive', |
| 244 field_group=property_['field_group'], | 242 field_group=property_['field_group'], |
| 245 size=1, | 243 size=1, |
| 246 default_value='true', | 244 default_value='true', |
| 245 has_custom_compare_and_copy=False, |
| 247 getter_method_name=method_name(name_for_methods), | 246 getter_method_name=method_name(name_for_methods), |
| 248 setter_method_name=method_name(join_name('set', name_for_methods)), | 247 setter_method_name=method_name(join_name('set', name_for_methods)), |
| 249 initial_method_name=method_name(join_name('initial', name_for_methods)), | 248 initial_method_name=method_name(join_name('initial', name_for_methods)), |
| 250 ) | 249 ) |
| 251 | 250 |
| 252 | 251 |
| 253 def _create_fields(properties): | 252 def _create_fields(properties): |
| 254 """ | 253 """ |
| 255 Create ComputedStyle fields from properties or nonproperties and return a li
st of Field objects. | 254 Create ComputedStyle fields from properties and return a list of Field objec
ts. |
| 256 """ | 255 """ |
| 257 fields = [] | 256 fields = [] |
| 258 for property_ in properties: | 257 for property_ in properties: |
| 259 # Only generate properties that have a field template | 258 # Only generate properties that have a field template |
| 260 if property_['field_template'] is not None: | 259 if property_['field_template'] is not None: |
| 261 # If the property is independent, add the single-bit sized isInherit
ed flag | 260 # If the property is independent, add the single-bit sized isInherit
ed flag |
| 262 # to the list of Fields as well. | 261 # to the list of Fields as well. |
| 263 if property_['independent']: | 262 if property_['independent']: |
| 264 fields.append(_create_inherited_flag_field(property_)) | 263 fields.append(_create_inherited_flag_field(property_)) |
| 265 | 264 |
| 266 # TODO(shend): Get rid of the property/nonproperty field roles. | 265 fields.append(_create_property_field(property_)) |
| 267 # If the field has_custom_compare_and_copy, then it does not appear
in | |
| 268 # ComputedStyle::operator== and ComputedStyle::CopyNonInheritedFromC
ached. | |
| 269 field_role = 'nonproperty' if property_['has_custom_compare_and_copy
'] else 'property' | |
| 270 fields.append(_create_field(field_role, property_)) | |
| 271 | 266 |
| 272 return fields | 267 return fields |
| 273 | 268 |
| 274 | 269 |
| 275 def _reorder_fields(fields): | 270 def _reorder_fields(fields): |
| 276 """ | 271 """ |
| 277 Returns a list of fields ordered to minimise padding. | 272 Returns a list of fields ordered to minimise padding. |
| 278 """ | 273 """ |
| 279 # Separate out bit fields from non bit fields | 274 # Separate out bit fields from non bit fields |
| 280 bit_fields = [field for field in fields if field.is_bit_field] | 275 bit_fields = [field for field in fields if field.is_bit_field] |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 | 373 |
| 379 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 374 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
| 380 def generate_base_computed_style_constants(self): | 375 def generate_base_computed_style_constants(self): |
| 381 return { | 376 return { |
| 382 'properties': self._properties, | 377 'properties': self._properties, |
| 383 'enums': self._generated_enums, | 378 'enums': self._generated_enums, |
| 384 } | 379 } |
| 385 | 380 |
| 386 if __name__ == '__main__': | 381 if __name__ == '__main__': |
| 387 json5_generator.Maker(ComputedStyleBaseWriter).main() | 382 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |