| 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 ( | 13 from name_utilities import ( |
| 14 enum_for_css_keyword, enum_type_name, enum_value_name, class_member_name, me
thod_name | 14 enum_for_css_keyword, enum_type_name, enum_value_name, class_member_name, me
thod_name |
| 15 ) | 15 ) |
| 16 from collections import OrderedDict |
| 16 | 17 |
| 17 | 18 |
| 18 # Temporary hard-coded list of fields that are not CSS properties. | 19 # Temporary hard-coded list of fields that are not CSS properties. |
| 19 # TODO(shend): Put this into its own JSON5 file. | 20 # TODO(shend): Put this into its own JSON5 file. |
| 20 NONPROPERTIES = [ | 21 NONPROPERTIES = [ |
| 21 {'name': 'IsLink', 'field_template': 'monotonic_flag', | 22 {'name': 'IsLink', 'field_template': 'monotonic_flag', |
| 22 'inherited': False, 'independent': False}, | 23 'inherited': False, 'independent': False}, |
| 23 {'name': 'OriginalDisplay', 'field_template': 'keyword', 'initial_keyword':
'inline', | 24 {'name': 'OriginalDisplay', 'field_template': 'keyword', 'initial_keyword':
'inline', |
| 24 'type_name': 'EDisplay', 'inherited': False, 'independent': False, | 25 'type_name': 'EDisplay', 'inherited': False, 'independent': False, |
| 25 'keywords': [ | 26 'keywords': [ |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 """ | 132 """ |
| 132 include_paths = set() | 133 include_paths = set() |
| 133 for property_ in properties: | 134 for property_ in properties: |
| 134 if property_['field_type_path'] is not None: | 135 if property_['field_type_path'] is not None: |
| 135 include_paths.add(property_['field_type_path'] + '.h') | 136 include_paths.add(property_['field_type_path'] + '.h') |
| 136 return list(sorted(include_paths)) | 137 return list(sorted(include_paths)) |
| 137 | 138 |
| 138 | 139 |
| 139 def _create_enums(properties): | 140 def _create_enums(properties): |
| 140 """ | 141 """ |
| 141 Returns a dictionary of enums to be generated, enum name -> [list of enum va
lues] | 142 Returns an OrderedDict of enums to be generated, enum name -> [list of enum
values] |
| 142 """ | 143 """ |
| 143 enums = {} | 144 enums = {} |
| 144 for property_ in properties: | 145 for property_ in properties: |
| 145 # Only generate enums for keyword properties that use the default field_
type_path. | 146 # Only generate enums for keyword properties that use the default field_
type_path. |
| 146 if property_['field_template'] == 'keyword' and property_['field_type_pa
th'] is None: | 147 if property_['field_template'] == 'keyword' and property_['field_type_pa
th'] is None: |
| 147 enum_name = property_['type_name'] | 148 enum_name = property_['type_name'] |
| 148 enum_values = [enum_value_name(k) for k in property_['keywords']] | 149 enum_values = [enum_value_name(k) for k in property_['keywords']] |
| 149 | 150 |
| 150 if enum_name in enums: | 151 if enum_name in enums: |
| 151 # There's an enum with the same name, check if the enum values a
re the same | 152 # There's an enum with the same name, check if the enum values a
re the same |
| 152 assert set(enums[enum_name]) == set(enum_values), \ | 153 assert set(enums[enum_name]) == set(enum_values), \ |
| 153 ("'" + property_['name'] + "' can't have type_name '" + enum
_name + "' " | 154 ("'" + property_['name'] + "' can't have type_name '" + enum
_name + "' " |
| 154 "because it was used by a previous property, but with a dif
ferent set of keywords. " | 155 "because it was used by a previous property, but with a dif
ferent set of keywords. " |
| 155 "Either give it a different name or ensure the keywords are
the same.") | 156 "Either give it a different name or ensure the keywords are
the same.") |
| 156 | 157 |
| 157 enums[enum_name] = enum_values | 158 enums[enum_name] = enum_values |
| 158 | 159 |
| 159 return enums | 160 # Return the enums sorted by key (enum name) |
| 161 return OrderedDict(sorted(enums.items(), key=lambda t: t[0])) |
| 160 | 162 |
| 161 | 163 |
| 162 def _create_field(field_role, property_): | 164 def _create_field(field_role, property_): |
| 163 """ | 165 """ |
| 164 Create a property or nonproperty field. | 166 Create a property or nonproperty field. |
| 165 """ | 167 """ |
| 166 assert field_role in ('property', 'nonproperty') | 168 assert field_role in ('property', 'nonproperty') |
| 167 | 169 |
| 168 name_for_methods = property_['name_for_methods'] | 170 name_for_methods = property_['name_for_methods'] |
| 169 | 171 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 # padding, group fields into buckets so that as many buckets as possible | 243 # padding, group fields into buckets so that as many buckets as possible |
| 242 # are exactly 32 bits. Although this greedy approach may not always | 244 # are exactly 32 bits. Although this greedy approach may not always |
| 243 # produce the optimal solution, we add a static_assert to the code to | 245 # produce the optimal solution, we add a static_assert to the code to |
| 244 # ensure ComputedStyleBase results in the expected size. If that | 246 # ensure ComputedStyleBase results in the expected size. If that |
| 245 # static_assert fails, this code is falling into the small number of | 247 # static_assert fails, this code is falling into the small number of |
| 246 # cases that are suboptimal, and may need to be rethought. | 248 # cases that are suboptimal, and may need to be rethought. |
| 247 # For more details on packing bitfields to reduce padding, see: | 249 # For more details on packing bitfields to reduce padding, see: |
| 248 # http://www.catb.org/esr/structure-packing/#_bitfields | 250 # http://www.catb.org/esr/structure-packing/#_bitfields |
| 249 field_buckets = [] | 251 field_buckets = [] |
| 250 # Consider fields in descending order of size to reduce fragmentation | 252 # Consider fields in descending order of size to reduce fragmentation |
| 251 # when they are selected. | 253 # when they are selected. Ties broken in alphabetical order by name. |
| 252 for field in sorted(fields, key=lambda f: f.size, reverse=True): | 254 for field in sorted(fields, key=lambda f: (-f.size, f.name)): |
| 253 added_to_bucket = False | 255 added_to_bucket = False |
| 254 # Go through each bucket and add this field if it will not increase | 256 # Go through each bucket and add this field if it will not increase |
| 255 # the bucket's size to larger than 32 bits. Otherwise, make a new | 257 # the bucket's size to larger than 32 bits. Otherwise, make a new |
| 256 # bucket containing only this field. | 258 # bucket containing only this field. |
| 257 for bucket in field_buckets: | 259 for bucket in field_buckets: |
| 258 if sum(f.size for f in bucket) + field.size <= 32: | 260 if sum(f.size for f in bucket) + field.size <= 32: |
| 259 bucket.append(field) | 261 bucket.append(field) |
| 260 added_to_bucket = True | 262 added_to_bucket = True |
| 261 break | 263 break |
| 262 if not added_to_bucket: | 264 if not added_to_bucket: |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 'mapping': [(enum_value_name(k), enum_for_css_keyword(k)) fo
r k in property_['keywords']], | 369 'mapping': [(enum_value_name(k), enum_for_css_keyword(k)) fo
r k in property_['keywords']], |
| 368 } | 370 } |
| 369 | 371 |
| 370 return { | 372 return { |
| 371 'include_paths': self._include_paths, | 373 'include_paths': self._include_paths, |
| 372 'mappings': mappings, | 374 'mappings': mappings, |
| 373 } | 375 } |
| 374 | 376 |
| 375 if __name__ == '__main__': | 377 if __name__ == '__main__': |
| 376 json5_generator.Maker(ComputedStyleBaseWriter).main() | 378 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |