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 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 def _num_32_bit_words_for_bit_fields(bit_fields): | 44 def _num_32_bit_words_for_bit_fields(bit_fields): |
| 45 """Gets the number of 32 bit unsigned integers needed store a list of bit fi elds.""" | 45 """Gets the number of 32 bit unsigned integers needed store a list of bit fi elds.""" |
| 46 num_buckets, cur_bucket = 0, 0 | 46 num_buckets, cur_bucket = 0, 0 |
| 47 for field in bit_fields: | 47 for field in bit_fields: |
| 48 if field.size + cur_bucket > 32: | 48 if field.size + cur_bucket > 32: |
| 49 num_buckets += 1 | 49 num_buckets += 1 |
| 50 cur_bucket = 0 | 50 cur_bucket = 0 |
| 51 cur_bucket += field.size | 51 cur_bucket += field.size |
| 52 return num_buckets + (cur_bucket > 0) | 52 return num_buckets + (cur_bucket > 0) |
| 53 | 53 |
| 54 | |
|
nainar
2017/05/11 04:04:08
oops. Added this in.
nainar
2017/05/11 06:00:08
Removed.
| |
| 55 class Group(object): | 54 class Group(object): |
| 56 """Represents a group of fields stored together in a class. | 55 """Represents a group of fields stored together in a class. |
| 57 | 56 |
| 58 Attributes: | 57 Attributes: |
| 59 name: The name of the group as a string. | 58 name: The name of the group as a string. |
| 60 subgroups: List of Group instances that are stored as subgroups under th is group. | 59 subgroups: List of Group instances that are stored as subgroups under th is group. |
| 61 fields: List of Field instances stored directly under this group. | 60 fields: List of Field instances stored directly under this group. |
| 62 """ | 61 """ |
| 63 def __init__(self, name, subgroups, fields): | 62 def __init__(self, name, subgroups, fields): |
| 64 self.name = name | 63 self.name = name |
| 65 self.subgroups = subgroups | 64 self.subgroups = subgroups |
| 66 self.fields = fields | 65 self.fields = fields |
| 67 self.type_name = class_name(join_name('style', name, 'data')) | 66 self.type_name = class_name(join_name('style', name, 'data')) |
| 68 self.member_name = class_member_name(join_name(name, 'data')) | 67 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( | 68 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 | 69 field for field in fields if field.is_bit_field |
| 71 ) | 70 ) |
| 72 | 71 |
| 73 # Recursively get all the fields in the subgroups as well | 72 # 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 | 73 self.all_fields = _flatten_list(subgroup.all_fields for subgroup in subg roups) + fields |
| 75 | 74 |
| 76 | 75 |
| 76 class DiffGroup(object): | |
| 77 """Represents a group of expressions and subgroups that need to be diffed | |
| 78 for a function in ComputedStyle. | |
| 79 | |
| 80 Attributes: | |
| 81 subgroups: List of DiffGroup instances that are stored as subgroups unde r this group. | |
| 82 expressions: List of functions that are on this group that need to be di ffed. | |
|
shend
2017/05/11 05:00:59
"List of expressions"
nainar
2017/05/11 06:00:08
Done.
| |
| 83 """ | |
| 84 def __init__(self, group_name, subgroups, expressions): | |
| 85 self.group_name = group_name | |
| 86 self.subgroups = subgroups | |
| 87 self.expressions = expressions | |
| 88 | |
| 77 class Field(object): | 89 class Field(object): |
| 78 """ | 90 """ |
| 79 The generated ComputedStyle object is made up of a series of Fields. | 91 The generated ComputedStyle object is made up of a series of Fields. |
| 80 Each Field has a name, size, type, etc, and a bunch of attributes to | 92 Each Field has a name, size, type, etc, and a bunch of attributes to |
| 81 determine which methods it will be used in. | 93 determine which methods it will be used in. |
| 82 | 94 |
| 83 A Field also has enough information to use any storage type in C++, such as | 95 A Field also has enough information to use any storage type in C++, such as |
| 84 regular member variables, or more complex storage like vectors or hashmaps. | 96 regular member variables, or more complex storage like vectors or hashmaps. |
| 85 Almost all properties will have at least one Field, often more than one. | 97 Almost all properties will have at least one Field, often more than one. |
| 86 | 98 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 include_paths.add(property_['field_type_path'] + '.h') | 168 include_paths.add(property_['field_type_path'] + '.h') |
| 157 return list(sorted(include_paths)) | 169 return list(sorted(include_paths)) |
| 158 | 170 |
| 159 | 171 |
| 160 def _group_fields(fields): | 172 def _group_fields(fields): |
| 161 """Groups a list of fields by their group_name and returns the root group."" " | 173 """Groups a list of fields by their group_name and returns the root group."" " |
| 162 groups = defaultdict(list) | 174 groups = defaultdict(list) |
| 163 for field in fields: | 175 for field in fields: |
| 164 groups[field.group_name].append(field) | 176 groups[field.group_name].append(field) |
| 165 | 177 |
| 166 no_group = groups.pop(None) | 178 no_group = {} |
| 179 if groups.get(None): | |
| 180 no_group = groups.pop(None) | |
| 167 subgroups = [Group(group_name, [], _reorder_fields(fields)) for group_name, fields in groups.items()] | 181 subgroups = [Group(group_name, [], _reorder_fields(fields)) for group_name, fields in groups.items()] |
| 168 return Group('', subgroups=subgroups, fields=_reorder_fields(no_group)) | 182 return Group('', subgroups=subgroups, fields=_reorder_fields(no_group)) |
| 169 | 183 |
| 170 | 184 |
| 185 def _create_field(field_name, all_properties): | |
|
shend
2017/05/11 05:00:59
Hmm, I'm not quite sure why this is needed.
I thin
nainar
2017/05/11 06:00:08
Didn't realize root_group was a thing
| |
| 186 for property_ in all_properties: | |
| 187 if field_name == property_['name']: | |
| 188 return _create_property_field(property_) | |
| 189 | |
| 190 | |
| 191 def _create_expression(field): | |
|
shend
2017/05/11 05:00:59
maybe _getter_expression? Or even put this as a me
nainar
2017/05/11 06:00:08
Added it as a member on field
| |
| 192 if field.group_name: | |
| 193 return field.group_name + '_data_->' + class_member_name(field.name) | |
| 194 else: | |
| 195 return class_member_name(field.name) | |
| 196 | |
| 197 | |
| 198 def _match_groups_to_diff_groups(groups): | |
| 199 diff_groups_list = [] | |
| 200 if not groups: | |
| 201 return | |
| 202 for group in groups: | |
| 203 list_of_expressions = [] | |
| 204 for field in group.fields: | |
| 205 list_of_expressions.append(_create_expression(field)) | |
| 206 diff_group = DiffGroup(group.name + '_data_', _match_groups_to_diff_grou ps(group.subgroups), list_of_expressions) | |
| 207 diff_groups_list.append(diff_group) | |
| 208 return diff_groups_list | |
| 209 | |
| 210 | |
| 211 def _create_diff_groups(diff_function_inputs, all_properties): | |
|
shend
2017/05/11 05:00:59
As mentioned below, I believe this code would be e
nainar
2017/05/11 06:00:08
Done.
| |
| 212 diff_named_groups_map = {} | |
| 213 for entry in diff_function_inputs: | |
| 214 list_of_fields = [] | |
| 215 for field in entry['fields']: | |
| 216 list_of_fields.append(_create_field(field, all_properties)) | |
| 217 diff_named_groups_map[entry['name']] = _match_groups_to_diff_groups(_gro up_fields(list_of_fields).subgroups) | |
| 218 return diff_named_groups_map | |
| 219 | |
| 220 | |
| 171 def _create_enums(properties): | 221 def _create_enums(properties): |
| 172 """ | 222 """ |
| 173 Returns an OrderedDict of enums to be generated, enum name -> [list of enum values] | 223 Returns an OrderedDict of enums to be generated, enum name -> [list of enum values] |
| 174 """ | 224 """ |
| 175 enums = {} | 225 enums = {} |
| 176 for property_ in properties: | 226 for property_ in properties: |
| 177 # Only generate enums for keyword properties that use the default field_ type_path. | 227 # Only generate enums for keyword properties that use the default field_ type_path. |
| 178 if property_['field_template'] == 'keyword' and property_['field_type_pa th'] is None: | 228 if property_['field_template'] == 'keyword' and property_['field_type_pa th'] is None: |
| 179 enum_name = property_['type_name'] | 229 enum_name = property_['type_name'] |
| 180 enum_values = [enum_value_name(k) for k in property_['keywords']] | 230 enum_values = [enum_value_name(k) for k in property_['keywords']] |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 | 413 |
| 364 # Override the type name when field_type_path is specified | 414 # Override the type name when field_type_path is specified |
| 365 for property_ in all_properties: | 415 for property_ in all_properties: |
| 366 if property_['field_type_path']: | 416 if property_['field_type_path']: |
| 367 property_['type_name'] = property_['field_type_path'].split('/') [-1] | 417 property_['type_name'] = property_['field_type_path'].split('/') [-1] |
| 368 | 418 |
| 369 self._generated_enums = _create_enums(all_properties) | 419 self._generated_enums = _create_enums(all_properties) |
| 370 | 420 |
| 371 all_fields = _create_fields(all_properties) | 421 all_fields = _create_fields(all_properties) |
| 372 | 422 |
| 423 self._diff_functions_map = _create_diff_groups(json5_generator.Json5File .load_from_files( | |
| 424 [json5_file_paths[2]] | |
| 425 ).name_dictionaries, all_properties) | |
| 426 | |
| 373 # Organise fields into a tree structure where the root group | 427 # Organise fields into a tree structure where the root group |
| 374 # is ComputedStyleBase. | 428 # is ComputedStyleBase. |
| 375 self._root_group = _group_fields(all_fields) | 429 self._root_group = _group_fields(all_fields) |
| 376 | 430 |
| 377 self._include_paths = _get_include_paths(all_properties) | 431 self._include_paths = _get_include_paths(all_properties) |
| 378 self._outputs = { | 432 self._outputs = { |
| 379 'ComputedStyleBase.h': self.generate_base_computed_style_h, | 433 'ComputedStyleBase.h': self.generate_base_computed_style_h, |
| 380 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, | 434 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, |
| 381 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co nstants, | 435 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co nstants, |
| 382 } | 436 } |
| 383 | 437 |
| 384 @template_expander.use_jinja('ComputedStyleBase.h.tmpl', tests={'in': lambda a, b: a in b}) | 438 @template_expander.use_jinja('ComputedStyleBase.h.tmpl', tests={'in': lambda a, b: a in b}) |
| 385 def generate_base_computed_style_h(self): | 439 def generate_base_computed_style_h(self): |
| 386 return { | 440 return { |
| 387 'properties': self._properties, | 441 'properties': self._properties, |
| 388 'enums': self._generated_enums, | 442 'enums': self._generated_enums, |
| 389 'include_paths': self._include_paths, | 443 'include_paths': self._include_paths, |
| 390 'computed_style': self._root_group, | 444 'computed_style': self._root_group, |
| 391 } | 445 } |
| 392 | 446 |
| 393 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl', tests={'in': lamb da a, b: a in b}) | 447 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl', tests={'in': lamb da a, b: a in b}) |
| 394 def generate_base_computed_style_cpp(self): | 448 def generate_base_computed_style_cpp(self): |
| 395 return { | 449 return { |
| 396 'properties': self._properties, | 450 'properties': self._properties, |
| 397 'enums': self._generated_enums, | 451 'enums': self._generated_enums, |
| 398 'computed_style': self._root_group, | 452 'computed_style': self._root_group, |
| 453 'diff_functions_map': self._diff_functions_map, | |
| 399 } | 454 } |
| 400 | 455 |
| 401 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 456 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
| 402 def generate_base_computed_style_constants(self): | 457 def generate_base_computed_style_constants(self): |
| 403 return { | 458 return { |
| 404 'properties': self._properties, | 459 'properties': self._properties, |
| 405 'enums': self._generated_enums, | 460 'enums': self._generated_enums, |
| 406 } | 461 } |
| 407 | 462 |
| 408 if __name__ == '__main__': | 463 if __name__ == '__main__': |
| 409 json5_generator.Maker(ComputedStyleBaseWriter).main() | 464 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |