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 |