Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: third_party/WebKit/Source/build/scripts/make_computed_style_base.py

Issue 2879563002: Refactor code generation to allow us to diff generic expressions and not just fields (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698