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 |