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 |