| 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 |
| 11 import make_style_builder | 11 import make_style_builder |
| 12 | 12 |
| 13 from name_utilities import camel_case, lower_first, upper_first_letter | 13 from name_utilities import camel_case, lower_first, upper_first_letter, enum_for
_css_keyword |
| 14 | 14 |
| 15 | 15 |
| 16 # Temporary hard-coded list of fields that are not CSS properties. | 16 # Temporary hard-coded list of fields that are not CSS properties. |
| 17 # Ideally these would be specified in a .in or .json5 file. | 17 # Ideally these would be specified in a .in or .json5 file. |
| 18 NONPROPERTY_FIELDS = set([ | 18 NONPROPERTY_FIELDS = set([ |
| 19 # Style can not be shared. | 19 # Style can not be shared. |
| 20 'unique', | 20 'unique', |
| 21 ]) | 21 ]) |
| 22 | 22 |
| 23 | 23 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 def _create_property_field(property_): | 126 def _create_property_field(property_): |
| 127 """ | 127 """ |
| 128 Create a property field from a CSS property and return the Field object. | 128 Create a property field from a CSS property and return the Field object. |
| 129 """ | 129 """ |
| 130 property_name = property_['name_for_methods'] | 130 property_name = property_['name_for_methods'] |
| 131 property_name_lower = lower_first(property_name) | 131 property_name_lower = lower_first(property_name) |
| 132 | 132 |
| 133 # From the Blink style guide: Other data members should be prefixed by "m_".
[names-data-members] | 133 # From the Blink style guide: Other data members should be prefixed by "m_".
[names-data-members] |
| 134 field_name = 'm_' + property_name_lower | 134 field_name = 'm_' + property_name_lower |
| 135 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for
non-enums | 135 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for
non-enums |
| 136 | 136 type_name = property_['type_name'] |
| 137 # Separate the type path from the type name, if specified. | |
| 138 if property_['field_type_path']: | |
| 139 type_name = property_['field_type_path'].split('/')[-1] | |
| 140 else: | |
| 141 type_name = property_['type_name'] | |
| 142 | 137 |
| 143 # For now, the getter name should match the field name. Later, getter names | 138 # For now, the getter name should match the field name. Later, getter names |
| 144 # will start with an uppercase letter, so if they conflict with the type nam
e, | 139 # will start with an uppercase letter, so if they conflict with the type nam
e, |
| 145 # add 'get' to the front. | 140 # add 'get' to the front. |
| 146 getter_method_name = property_name_lower | 141 getter_method_name = property_name_lower |
| 147 if type_name == property_name: | 142 if type_name == property_name: |
| 148 getter_method_name = 'get' + property_name | 143 getter_method_name = 'get' + property_name |
| 149 | 144 |
| 150 assert property_['initial_keyword'] is not None, \ | 145 assert property_['initial_keyword'] is not None, \ |
| 151 ('MakeComputedStyleBase requires an initial keyword for keyword fields,
none specified ' | 146 ('MakeComputedStyleBase requires an initial keyword for keyword fields,
none specified ' |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 return field_buckets | 267 return field_buckets |
| 273 | 268 |
| 274 | 269 |
| 275 class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter): | 270 class ComputedStyleBaseWriter(make_style_builder.StyleBuilderWriter): |
| 276 def __init__(self, json5_file_path): | 271 def __init__(self, json5_file_path): |
| 277 super(ComputedStyleBaseWriter, self).__init__(json5_file_path) | 272 super(ComputedStyleBaseWriter, self).__init__(json5_file_path) |
| 278 self._outputs = { | 273 self._outputs = { |
| 279 'ComputedStyleBase.h': self.generate_base_computed_style_h, | 274 'ComputedStyleBase.h': self.generate_base_computed_style_h, |
| 280 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, | 275 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, |
| 281 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co
nstants, | 276 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co
nstants, |
| 277 'CSSValueIDMappingsGenerated.h': self.generate_css_value_mappings, |
| 282 } | 278 } |
| 283 | 279 |
| 280 property_values = self._properties.values() |
| 281 |
| 282 # Override the type name when field_type_path is specified |
| 283 for property_ in property_values: |
| 284 if property_['field_type_path']: |
| 285 property_['type_name'] = property_['field_type_path'].split('/')
[-1] |
| 286 |
| 284 # Create all the enums used by properties | 287 # Create all the enums used by properties |
| 285 self._generated_enums = _create_enums(self._properties.values()) | 288 self._generated_enums = _create_enums(self._properties.values()) |
| 286 | 289 |
| 287 # Create all the fields | 290 # Create all the fields |
| 288 all_fields = _create_fields(self._properties.values()) | 291 all_fields = _create_fields(self._properties.values()) |
| 289 | 292 |
| 290 # Group fields into buckets | 293 # Group fields into buckets |
| 291 field_buckets = _pack_fields(all_fields) | 294 field_buckets = _pack_fields(all_fields) |
| 292 | 295 |
| 293 # The expected size of ComputedStyleBase is equivalent to as many words | 296 # The expected size of ComputedStyleBase is equivalent to as many words |
| (...skipping 15 matching lines...) Expand all Loading... |
| 309 assert self._expected_total_field_bytes == real_total_field_bytes, \ | 312 assert self._expected_total_field_bytes == real_total_field_bytes, \ |
| 310 ('The field packing algorithm produced %s bytes, optimal is %s bytes
' % | 313 ('The field packing algorithm produced %s bytes, optimal is %s bytes
' % |
| 311 (self._expected_total_field_bytes, real_total_field_bytes)) | 314 (self._expected_total_field_bytes, real_total_field_bytes)) |
| 312 | 315 |
| 313 # Order the fields so fields in each bucket are adjacent. | 316 # Order the fields so fields in each bucket are adjacent. |
| 314 self._fields = [] | 317 self._fields = [] |
| 315 for bucket in field_buckets: | 318 for bucket in field_buckets: |
| 316 for field in bucket: | 319 for field in bucket: |
| 317 self._fields.append(field) | 320 self._fields.append(field) |
| 318 | 321 |
| 322 self._include_paths = _get_include_paths(self._properties.values()) |
| 323 |
| 319 | 324 |
| 320 @template_expander.use_jinja('ComputedStyleBase.h.tmpl') | 325 @template_expander.use_jinja('ComputedStyleBase.h.tmpl') |
| 321 def generate_base_computed_style_h(self): | 326 def generate_base_computed_style_h(self): |
| 322 return { | 327 return { |
| 323 'properties': self._properties, | 328 'properties': self._properties, |
| 324 'enums': self._generated_enums, | 329 'enums': self._generated_enums, |
| 325 'include_paths': _get_include_paths(self._properties.values()), | 330 'include_paths': self._include_paths, |
| 326 'fields': self._fields, | 331 'fields': self._fields, |
| 327 'expected_total_field_bytes': self._expected_total_field_bytes, | 332 'expected_total_field_bytes': self._expected_total_field_bytes, |
| 328 } | 333 } |
| 329 | 334 |
| 330 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl') | 335 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl') |
| 331 def generate_base_computed_style_cpp(self): | 336 def generate_base_computed_style_cpp(self): |
| 332 return { | 337 return { |
| 333 'properties': self._properties, | 338 'properties': self._properties, |
| 334 'enums': self._generated_enums, | 339 'enums': self._generated_enums, |
| 335 'fields': self._fields, | 340 'fields': self._fields, |
| 336 'expected_total_field_bytes': self._expected_total_field_bytes, | 341 'expected_total_field_bytes': self._expected_total_field_bytes, |
| 337 } | 342 } |
| 338 | 343 |
| 339 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 344 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
| 340 def generate_base_computed_style_constants(self): | 345 def generate_base_computed_style_constants(self): |
| 341 return { | 346 return { |
| 342 'properties': self._properties, | 347 'properties': self._properties, |
| 343 'enums': self._generated_enums, | 348 'enums': self._generated_enums, |
| 344 'fields': self._fields, | 349 'fields': self._fields, |
| 345 'expected_total_field_bytes': self._expected_total_field_bytes, | 350 'expected_total_field_bytes': self._expected_total_field_bytes, |
| 346 } | 351 } |
| 347 | 352 |
| 353 @template_expander.use_jinja('CSSValueIDMappingsGenerated.h.tmpl') |
| 354 def generate_css_value_mappings(self): |
| 355 mappings = {} |
| 356 |
| 357 for property_ in self._properties.values(): |
| 358 if property_['field_template'] == 'keyword': |
| 359 mappings[property_['type_name']] = { |
| 360 'default_value': 'k' + camel_case(property_['initial_keyword
']), |
| 361 'mapping': [('k' + camel_case(k), enum_for_css_keyword(k)) f
or k in property_['keywords']], |
| 362 } |
| 363 |
| 364 return { |
| 365 'include_paths': self._include_paths, |
| 366 'mappings': mappings, |
| 367 } |
| 368 |
| 348 if __name__ == '__main__': | 369 if __name__ == '__main__': |
| 349 json5_generator.Maker(ComputedStyleBaseWriter).main() | 370 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |