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 56 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 DiffGroup(object): | |
| 78 """Represents a group of expressions and subgroups that need to be diffed | |
| 79 for a function in ComputedStyle. | |
| 80 | |
| 81 Attributes: | |
| 82 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. | |
| 84 """ | |
| 85 def __init__(self, group_name): | |
| 86 self.group_name = group_name | |
| 87 self.subgroups = [] | |
| 88 self.expressions = [] | |
| 89 | |
|
alancutter (OOO until 2018)
2017/05/12 04:04:50
Two newlines between class definitions.
nainar
2017/05/12 05:05:36
Done.
| |
| 77 class Field(object): | 90 class Field(object): |
| 78 """ | 91 """ |
| 79 The generated ComputedStyle object is made up of a series of Fields. | 92 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 | 93 Each Field has a name, size, type, etc, and a bunch of attributes to |
| 81 determine which methods it will be used in. | 94 determine which methods it will be used in. |
| 82 | 95 |
| 83 A Field also has enough information to use any storage type in C++, such as | 96 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. | 97 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. | 98 Almost all properties will have at least one Field, often more than one. |
| 86 | 99 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 | 145 |
| 133 # Method names | 146 # Method names |
| 134 # TODO(nainar): Method name generation is inconsistent. Fix. | 147 # TODO(nainar): Method name generation is inconsistent. Fix. |
| 135 self.getter_method_name = getter_method_name | 148 self.getter_method_name = getter_method_name |
| 136 self.setter_method_name = setter_method_name | 149 self.setter_method_name = setter_method_name |
| 137 self.internal_getter_method_name = method_name(join_name(getter_method_n ame, 'Internal')) | 150 self.internal_getter_method_name = method_name(join_name(getter_method_n ame, 'Internal')) |
| 138 self.internal_mutable_method_name = method_name(join_name('Mutable', nam e_for_methods, 'Internal')) | 151 self.internal_mutable_method_name = method_name(join_name('Mutable', nam e_for_methods, 'Internal')) |
| 139 self.internal_setter_method_name = method_name(join_name(setter_method_n ame, 'Internal')) | 152 self.internal_setter_method_name = method_name(join_name(setter_method_n ame, 'Internal')) |
| 140 self.initial_method_name = initial_method_name | 153 self.initial_method_name = initial_method_name |
| 141 self.resetter_method_name = method_name(join_name('Reset', name_for_meth ods)) | 154 self.resetter_method_name = method_name(join_name('Reset', name_for_meth ods)) |
| 155 if self.group_name: | |
| 156 self.getter_expression = self.group_member_name + '->' + class_membe r_name(self.name) | |
| 157 else: | |
| 158 self.getter_expression = class_member_name(self.name) | |
| 142 | 159 |
| 143 # If the size of the field is not None, it means it is a bit field | 160 # If the size of the field is not None, it means it is a bit field |
| 144 self.is_bit_field = self.size is not None | 161 self.is_bit_field = self.size is not None |
| 145 | 162 |
| 146 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st r(kwargs) | 163 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st r(kwargs) |
| 147 | 164 |
| 148 | 165 |
| 149 def _get_include_paths(properties): | 166 def _get_include_paths(properties): |
| 150 """ | 167 """ |
| 151 Get a list of paths that need to be included for ComputedStyleBase. | 168 Get a list of paths that need to be included for ComputedStyleBase. |
| 152 """ | 169 """ |
| 153 include_paths = set() | 170 include_paths = set() |
| 154 for property_ in properties: | 171 for property_ in properties: |
| 155 if property_['field_type_path'] is not None: | 172 if property_['field_type_path'] is not None: |
| 156 include_paths.add(property_['field_type_path'] + '.h') | 173 include_paths.add(property_['field_type_path'] + '.h') |
| 157 return list(sorted(include_paths)) | 174 return list(sorted(include_paths)) |
| 158 | 175 |
| 159 | 176 |
| 160 def _group_fields(fields): | 177 def _group_fields(fields): |
| 161 """Groups a list of fields by their group_name and returns the root group."" " | 178 """Groups a list of fields by their group_name and returns the root group."" " |
| 162 groups = defaultdict(list) | 179 groups = defaultdict(list) |
| 163 for field in fields: | 180 for field in fields: |
| 164 groups[field.group_name].append(field) | 181 groups[field.group_name].append(field) |
| 165 | 182 |
| 166 no_group = groups.pop(None) | 183 no_group = groups.pop(None) |
| 167 subgroups = [Group(group_name, [], _reorder_fields(fields)) for group_name, fields in groups.items()] | 184 subgroups = [Group(group_name, [], _reorder_fields(fields)) for group_name, fields in groups.items()] |
| 168 return Group('', subgroups=subgroups, fields=_reorder_fields(no_group)) | 185 return Group('', subgroups=subgroups, fields=_reorder_fields(no_group)) |
| 169 | 186 |
| 170 | 187 |
| 188 def _create_diff_groups_map(diff_function_inputs, root_group): | |
| 189 diff_functions_map = {} | |
| 190 for entry in diff_function_inputs: | |
| 191 diff_functions_map[entry['name']] = _create_diff_groups(entry['fields'], root_group) | |
| 192 return diff_functions_map | |
| 193 | |
| 194 | |
| 195 def _create_diff_groups(fields_to_diff, root_group): | |
| 196 diff_group = DiffGroup(root_group.member_name) | |
| 197 for subgroup in root_group.subgroups: | |
| 198 if any(field.property_name in fields_to_diff for field in subgroup.all_f ields): | |
| 199 diff_group.subgroups.append(_create_diff_groups(fields_to_diff, subg roup)) | |
| 200 for field in root_group.fields: | |
| 201 if field.property_name in fields_to_diff: | |
| 202 diff_group.expressions.append(field.getter_expression) | |
| 203 return diff_group | |
| 204 | |
| 205 | |
| 171 def _create_enums(properties): | 206 def _create_enums(properties): |
| 172 """ | 207 """ |
| 173 Returns an OrderedDict of enums to be generated, enum name -> [list of enum values] | 208 Returns an OrderedDict of enums to be generated, enum name -> [list of enum values] |
| 174 """ | 209 """ |
| 175 enums = {} | 210 enums = {} |
| 176 for property_ in properties: | 211 for property_ in properties: |
| 177 # Only generate enums for keyword properties that use the default field_ type_path. | 212 # 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: | 213 if property_['field_template'] == 'keyword' and property_['field_type_pa th'] is None: |
| 179 enum_name = property_['type_name'] | 214 enum_name = property_['type_name'] |
| 180 enum_values = [enum_value_name(k) for k in property_['keywords']] | 215 enum_values = [enum_value_name(k) for k in property_['keywords']] |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 if property_['field_type_path']: | 401 if property_['field_type_path']: |
| 367 property_['type_name'] = property_['field_type_path'].split('/') [-1] | 402 property_['type_name'] = property_['field_type_path'].split('/') [-1] |
| 368 | 403 |
| 369 self._generated_enums = _create_enums(all_properties) | 404 self._generated_enums = _create_enums(all_properties) |
| 370 | 405 |
| 371 all_fields = _create_fields(all_properties) | 406 all_fields = _create_fields(all_properties) |
| 372 | 407 |
| 373 # Organise fields into a tree structure where the root group | 408 # Organise fields into a tree structure where the root group |
| 374 # is ComputedStyleBase. | 409 # is ComputedStyleBase. |
| 375 self._root_group = _group_fields(all_fields) | 410 self._root_group = _group_fields(all_fields) |
| 411 self._diff_functions_map = _create_diff_groups_map(json5_generator.Json5 File.load_from_files( | |
| 412 [json5_file_paths[2]] | |
| 413 ).name_dictionaries, self._root_group) | |
| 376 | 414 |
| 377 self._include_paths = _get_include_paths(all_properties) | 415 self._include_paths = _get_include_paths(all_properties) |
| 378 self._outputs = { | 416 self._outputs = { |
| 379 'ComputedStyleBase.h': self.generate_base_computed_style_h, | 417 'ComputedStyleBase.h': self.generate_base_computed_style_h, |
| 380 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, | 418 'ComputedStyleBase.cpp': self.generate_base_computed_style_cpp, |
| 381 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co nstants, | 419 'ComputedStyleBaseConstants.h': self.generate_base_computed_style_co nstants, |
| 382 } | 420 } |
| 383 | 421 |
| 384 @template_expander.use_jinja('ComputedStyleBase.h.tmpl', tests={'in': lambda a, b: a in b}) | 422 @template_expander.use_jinja('ComputedStyleBase.h.tmpl', tests={'in': lambda a, b: a in b}) |
| 385 def generate_base_computed_style_h(self): | 423 def generate_base_computed_style_h(self): |
| 386 return { | 424 return { |
| 387 'properties': self._properties, | 425 'properties': self._properties, |
| 388 'enums': self._generated_enums, | 426 'enums': self._generated_enums, |
| 389 'include_paths': self._include_paths, | 427 'include_paths': self._include_paths, |
| 390 'computed_style': self._root_group, | 428 'computed_style': self._root_group, |
| 391 } | 429 } |
| 392 | 430 |
| 393 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl', tests={'in': lamb da a, b: a in b}) | 431 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl', tests={'in': lamb da a, b: a in b}) |
| 394 def generate_base_computed_style_cpp(self): | 432 def generate_base_computed_style_cpp(self): |
| 395 return { | 433 return { |
| 396 'properties': self._properties, | 434 'properties': self._properties, |
| 397 'enums': self._generated_enums, | 435 'enums': self._generated_enums, |
| 398 'computed_style': self._root_group, | 436 'computed_style': self._root_group, |
| 437 'diff_functions_map': self._diff_functions_map, | |
| 399 } | 438 } |
| 400 | 439 |
| 401 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 440 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
| 402 def generate_base_computed_style_constants(self): | 441 def generate_base_computed_style_constants(self): |
| 403 return { | 442 return { |
| 404 'properties': self._properties, | 443 'properties': self._properties, |
| 405 'enums': self._generated_enums, | 444 'enums': self._generated_enums, |
| 406 } | 445 } |
| 407 | 446 |
| 408 if __name__ == '__main__': | 447 if __name__ == '__main__': |
| 409 json5_generator.Maker(ComputedStyleBaseWriter).main() | 448 json5_generator.Maker(ComputedStyleBaseWriter).main() |
| OLD | NEW |