Chromium Code Reviews| 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 class_name, join_name | 15 class_name, join_name |
| 16 ) | 16 ) |
| 17 from collections import defaultdict, OrderedDict | 17 from collections import defaultdict |
| 18 from itertools import chain | 18 from itertools import chain |
| 19 | 19 |
| 20 # Heuristic ordering of types from largest to smallest, used to sort fields by t heir alignment sizes. | 20 # Heuristic ordering of types from largest to smallest, used to sort fields by t heir alignment sizes. |
| 21 # Specifying the exact alignment sizes for each type is impossible because it's platform specific, | 21 # Specifying the exact alignment sizes for each type is impossible because it's platform specific, |
| 22 # so we define an ordering instead. | 22 # so we define an ordering instead. |
| 23 # The ordering comes from the data obtained in: | 23 # The ordering comes from the data obtained in: |
| 24 # https://codereview.chromium.org/2841413002 | 24 # https://codereview.chromium.org/2841413002 |
| 25 # TODO(shend): Put alignment sizes into code form, rather than linking to a CL w hich may disappear. | 25 # TODO(shend): Put alignment sizes into code form, rather than linking to a CL w hich may disappear. |
| 26 ALIGNMENT_ORDER = [ | 26 ALIGNMENT_ORDER = [ |
| 27 'double', | 27 'double', |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 self.type_name = class_name(join_name('style', name, 'data')) | 67 self.type_name = class_name(join_name('style', name, 'data')) |
| 68 self.member_name = class_member_name(join_name(name, 'data')) | 68 self.member_name = class_member_name(join_name(name, 'data')) |
| 69 self.num_32_bit_words_for_bit_fields = _num_32_bit_words_for_bit_fields( | 69 self.num_32_bit_words_for_bit_fields = _num_32_bit_words_for_bit_fields( |
| 70 field for field in fields if field.is_bit_field | 70 field for field in fields if field.is_bit_field |
| 71 ) | 71 ) |
| 72 | 72 |
| 73 # Recursively get all the fields in the subgroups as well | 73 # Recursively get all the fields in the subgroups as well |
| 74 self.all_fields = _flatten_list(subgroup.all_fields for subgroup in subg roups) + fields | 74 self.all_fields = _flatten_list(subgroup.all_fields for subgroup in subg roups) + fields |
| 75 | 75 |
| 76 | 76 |
| 77 class Enum(object): | |
| 78 """Represents a generated enum in ComputedStyleConstants.""" | |
|
nainar
2017/05/30 04:13:45
ComputedStyleBaseConstants
| |
| 79 def __init__(self, type_name, keywords, is_set): | |
| 80 self.type_name = type_name | |
| 81 self.values = [enum_value_name(keyword) for keyword in keywords] | |
| 82 self.is_set = is_set | |
|
nainar
2017/05/30 04:13:45
is_set -> is_subset
shend
2017/05/31 07:52:07
I decided not to change this one, since the enum i
| |
| 83 | |
| 84 | |
| 77 class DiffGroup(object): | 85 class DiffGroup(object): |
| 78 """Represents a group of expressions and subgroups that need to be diffed | 86 """Represents a group of expressions and subgroups that need to be diffed |
| 79 for a function in ComputedStyle. | 87 for a function in ComputedStyle. |
| 80 | 88 |
| 81 Attributes: | 89 Attributes: |
| 82 subgroups: List of DiffGroup instances that are stored as subgroups unde r this group. | 90 subgroups: List of DiffGroup instances that are stored as subgroups unde r this group. |
| 83 expressions: List of expression that are on this group that need to be d iffed. | 91 expressions: List of expression that are on this group that need to be d iffed. |
| 84 """ | 92 """ |
| 85 def __init__(self, group_name): | 93 def __init__(self, group_name): |
| 86 self.group_name = group_name | 94 self.group_name = group_name |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 if not field.is_inherited_flag and field.property_name in entry['fie ld_dependencies']: | 228 if not field.is_inherited_flag and field.property_name in entry['fie ld_dependencies']: |
| 221 diff_group.expressions.append(entry['method']) | 229 diff_group.expressions.append(entry['method']) |
| 222 for entry in predicates_to_test: | 230 for entry in predicates_to_test: |
| 223 for field in root_group.fields: | 231 for field in root_group.fields: |
| 224 if not field.is_inherited_flag and field.property_name in entry['fie ld_dependencies']: | 232 if not field.is_inherited_flag and field.property_name in entry['fie ld_dependencies']: |
| 225 diff_group.predicates.append(entry['predicate']) | 233 diff_group.predicates.append(entry['predicate']) |
| 226 return diff_group | 234 return diff_group |
| 227 | 235 |
| 228 | 236 |
| 229 def _create_enums(properties): | 237 def _create_enums(properties): |
| 230 """ | 238 """Returns a list of Enums to be generated""" |
| 231 Returns an OrderedDict of enums to be generated, enum name -> [list of enum values] | |
| 232 """ | |
| 233 enums = {} | 239 enums = {} |
| 234 for property_ in properties: | 240 for property_ in properties: |
| 235 # Only generate enums for keyword properties that do not require include s. | 241 # Only generate enums for keyword properties that do not require include s. |
| 236 if property_['field_template'] == 'keyword' and len(property_['include_p aths']) == 0: | 242 if property_['field_template'] in ('keyword', 'keyword_set') and len(pro perty_['include_paths']) == 0: |
|
nainar
2017/05/30 04:13:45
keyword_set -> keyword_subset
shend
2017/05/31 07:52:07
done.
| |
| 237 enum_name = property_['type_name'] | 243 enum = Enum(property_['type_name'], property_['keywords'], |
| 238 enum_values = [enum_value_name(k) for k in property_['keywords']] | 244 is_set=(property_['field_template'] == 'keyword_set')) |
| 239 | 245 |
| 240 if enum_name in enums: | 246 if property_['field_template'] == 'keyword_set': |
| 247 assert property_['keywords'][0] == 'none', \ | |
| 248 "First keyword in a 'keyword_set' field must be 'none' in '{ }'.".format(property_['name']) | |
| 249 | |
| 250 if enum.type_name in enums: | |
| 241 # There's an enum with the same name, check if the enum values a re the same | 251 # There's an enum with the same name, check if the enum values a re the same |
| 242 assert set(enums[enum_name]) == set(enum_values), \ | 252 assert set(enums[enum.type_name].values) == set(enum.values), \ |
| 243 ("'" + property_['name'] + "' can't have type_name '" + enum _name + "' " | 253 ("'" + property_['name'] + "' can't have type_name '" + enum .type_name + "' " |
| 244 "because it was used by a previous property, but with a dif ferent set of keywords. " | 254 "because it was used by a previous property, but with a dif ferent set of keywords. " |
| 245 "Either give it a different name or ensure the keywords are the same.") | 255 "Either give it a different name or ensure the keywords are the same.") |
| 246 | 256 |
| 247 enums[enum_name] = enum_values | 257 enums[enum.type_name] = enum |
| 248 | 258 |
| 249 # Return the enums sorted by key (enum name) | 259 # Return the enums sorted by type name |
| 250 return OrderedDict(sorted(enums.items(), key=lambda t: t[0])) | 260 return list(sorted(enums.values(), key=lambda e: e.type_name)) |
| 251 | 261 |
| 252 | 262 |
| 253 def _create_property_field(property_): | 263 def _create_property_field(property_): |
| 254 """ | 264 """ |
| 255 Create a property field. | 265 Create a property field. |
| 256 """ | 266 """ |
| 257 name_for_methods = property_['name_for_methods'] | 267 name_for_methods = property_['name_for_methods'] |
| 258 | 268 |
| 259 assert property_['default_value'] is not None, \ | 269 assert property_['default_value'] is not None, \ |
| 260 ('MakeComputedStyleBase requires an default value for all fields, none s pecified ' | 270 ('MakeComputedStyleBase requires an default value for all fields, none s pecified ' |
| 261 'for property ' + property_['name']) | 271 'for property ' + property_['name']) |
| 262 | 272 |
| 263 if property_['field_template'] == 'keyword': | 273 if property_['field_template'] == 'keyword': |
| 264 type_name = property_['type_name'] | 274 type_name = property_['type_name'] |
| 265 default_value = type_name + '::' + enum_value_name(property_['default_va lue']) | 275 default_value = type_name + '::' + enum_value_name(property_['default_va lue']) |
| 266 size = int(math.ceil(math.log(len(property_['keywords']), 2))) | 276 size = int(math.ceil(math.log(len(property_['keywords']), 2))) |
| 277 elif property_['field_template'] == 'keyword_set': | |
| 278 type_name = property_['type_name'] | |
| 279 default_value = type_name + '::' + enum_value_name(property_['default_va lue']) | |
| 280 size = len(property_['keywords']) - 1 # Subtract 1 for 'none' keyword | |
| 267 elif property_['field_template'] == 'storage_only': | 281 elif property_['field_template'] == 'storage_only': |
| 268 # 'storage_only' fields need to specify a size, type_name and default_va lue | 282 # 'storage_only' fields need to specify a size, type_name and default_va lue |
| 269 type_name = property_['type_name'] | 283 type_name = property_['type_name'] |
| 270 default_value = property_['default_value'] | 284 default_value = property_['default_value'] |
| 271 size = property_['field_size'] | 285 size = property_['field_size'] |
| 272 elif property_['field_template'] == 'external': | 286 elif property_['field_template'] == 'external': |
| 273 type_name = property_['type_name'] | 287 type_name = property_['type_name'] |
| 274 default_value = property_['default_value'] | 288 default_value = property_['default_value'] |
| 275 size = None | 289 size = None |
| 276 elif property_['field_template'] == 'primitive': | 290 elif property_['field_template'] == 'primitive': |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 | 471 |
| 458 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 472 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
| 459 def generate_base_computed_style_constants(self): | 473 def generate_base_computed_style_constants(self): |
| 460 return { | 474 return { |
| 461 'properties': self._properties, | 475 'properties': self._properties, |
| 462 'enums': self._generated_enums, | 476 'enums': self._generated_enums, |
| 463 } | 477 } |
| 464 | 478 |
| 465 if __name__ == '__main__': | 479 if __name__ == '__main__': |
| 466 json5_generator.Maker(ComputedStyleBaseWriter).main() | 480 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |