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

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

Issue 2756113002: Move naming related code in make_computed_style_base to name_utilities. (Closed)
Patch Set: Rebase Created 3 years, 9 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
11 import make_style_builder 11 import make_style_builder
12 12
13 from name_utilities import camel_case, lower_first, upper_first_letter, enum_for _css_keyword 13 from name_utilities import (
14 enum_for_css_keyword, enum_value_name, class_member_name, method_name
15 )
14 16
15 17
16 # Temporary hard-coded list of fields that are not CSS properties. 18 # Temporary hard-coded list of fields that are not CSS properties.
17 # Ideally these would be specified in a .json5 file. 19 # Ideally these would be specified in a .json5 file.
18 NONPROPERTY_FIELDS = [ 20 NONPROPERTY_FIELDS = [
19 {'name': 'isLink', 'field_template': 'monotonic_flag'}, 21 {'name': 'IsLink', 'field_template': 'monotonic_flag'},
20 # Style can not be shared. 22 # Style can not be shared.
21 {'name': 'unique', 'field_template': 'monotonic_flag'}, 23 {'name': 'Unique', 'field_template': 'monotonic_flag'},
22 # Whether this style is affected by these pseudo-classes. 24 # Whether this style is affected by these pseudo-classes.
23 {'name': 'affectedByFocus', 'field_template': 'monotonic_flag'}, 25 {'name': 'AffectedByFocus', 'field_template': 'monotonic_flag'},
24 {'name': 'affectedByHover', 'field_template': 'monotonic_flag'}, 26 {'name': 'AffectedByHover', 'field_template': 'monotonic_flag'},
25 {'name': 'affectedByActive', 'field_template': 'monotonic_flag'}, 27 {'name': 'AffectedByActive', 'field_template': 'monotonic_flag'},
26 {'name': 'affectedByDrag', 'field_template': 'monotonic_flag'}, 28 {'name': 'AffectedByDrag', 'field_template': 'monotonic_flag'},
27 # A non-inherited property references a variable or @apply is used 29 # A non-inherited property references a variable or @apply is used
28 {'name': 'hasVariableReferenceFromNonInheritedProperty', 'field_template': ' monotonic_flag'}, 30 {'name': 'HasVariableReferenceFromNonInheritedProperty', 'field_template': ' monotonic_flag'},
29 # Explicitly inherits a non-inherited property 31 # Explicitly inherits a non-inherited property
30 {'name': 'hasExplicitlyInheritedProperties', 'field_template': 'monotonic_fl ag'}, 32 {'name': 'HasExplicitlyInheritedProperties', 'field_template': 'monotonic_fl ag'},
31 # These properties only have generated storage, and their methods are handwr itten in ComputedStyle. 33 # These properties only have generated storage, and their methods are handwr itten in ComputedStyle.
32 # TODO(shend): Remove these fields and delete the 'storage_only' template. 34 # TODO(shend): Remove these fields and delete the 'storage_only' template.
33 {'name': 'emptyState', 'field_template': 'storage_only', 'size': 1} 35 {'name': 'EmptyState', 'field_template': 'storage_only', 'size': 1}
34 ] 36 ]
35 37
36 38
37 class Field(object): 39 class Field(object):
38 """ 40 """
39 The generated ComputedStyle object is made up of a series of Fields. 41 The generated ComputedStyle object is made up of a series of Fields.
40 Each Field has a name, size, type, etc, and a bunch of attributes to 42 Each Field has a name, size, type, etc, and a bunch of attributes to
41 determine which methods it will be used in. 43 determine which methods it will be used in.
42 44
43 A Field also has enough information to use any storage type in C++, such as 45 A Field also has enough information to use any storage type in C++, such as
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 116
115 def _create_enums(properties): 117 def _create_enums(properties):
116 """ 118 """
117 Returns a dictionary of enums to be generated, enum name -> [list of enum va lues] 119 Returns a dictionary of enums to be generated, enum name -> [list of enum va lues]
118 """ 120 """
119 enums = {} 121 enums = {}
120 for property_ in properties: 122 for property_ in properties:
121 # Only generate enums for keyword properties that use the default field_ type_path. 123 # Only generate enums for keyword properties that use the default field_ type_path.
122 if property_['field_template'] == 'keyword' and property_['field_type_pa th'] is None: 124 if property_['field_template'] == 'keyword' and property_['field_type_pa th'] is None:
123 enum_name = property_['type_name'] 125 enum_name = property_['type_name']
124 # From the Blink style guide: Enum members should use InterCaps with an initial capital letter. [names-enum-members] 126 enum_values = [enum_value_name(k) for k in property_['keywords']]
125 enum_values = [('k' + camel_case(k)) for k in property_['keywords']]
126 127
127 if enum_name in enums: 128 if enum_name in enums:
128 # There's an enum with the same name, check if the enum values a re the same 129 # There's an enum with the same name, check if the enum values a re the same
129 assert set(enums[enum_name]) == set(enum_values), \ 130 assert set(enums[enum_name]) == set(enum_values), \
130 ("'" + property_['name'] + "' can't have type_name '" + enum _name + "' " 131 ("'" + property_['name'] + "' can't have type_name '" + enum _name + "' "
131 "because it was used by a previous property, but with a dif ferent set of keywords. " 132 "because it was used by a previous property, but with a dif ferent set of keywords. "
132 "Either give it a different name or ensure the keywords are the same.") 133 "Either give it a different name or ensure the keywords are the same.")
133 134
134 enums[enum_name] = enum_values 135 enums[enum_name] = enum_values
135 136
136 return enums 137 return enums
137 138
138 139
139 def _create_property_field(property_): 140 def _create_property_field(property_):
140 """ 141 """
141 Create a property field from a CSS property and return the Field object. 142 Create a property field from a CSS property and return the Field object.
142 """ 143 """
143 property_name = property_['name_for_methods'] 144 name_for_methods = property_['name_for_methods']
144 property_name_lower = lower_first(property_name)
145 145
146 # From the Blink style guide: Other data members should be prefixed by "m_". [names-data-members]
147 field_name = 'm_' + property_name_lower
148 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for non-enums 146 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for non-enums
149 type_name = property_['type_name'] 147 type_name = property_['type_name']
150 148
151 # For now, the getter name should match the field name. Later, getter names 149 # For now, the getter name should match the field name. Later, getter names
152 # will start with an uppercase letter, so if they conflict with the type nam e, 150 # will start with an uppercase letter, so if they conflict with the type nam e,
153 # add 'get' to the front. 151 # add 'get' to the front.
154 getter_method_name = property_name_lower 152 if type_name != name_for_methods:
155 if type_name == property_name: 153 getter_method_name = method_name(name_for_methods)
156 getter_method_name = 'get' + property_name 154 else:
155 getter_method_name = method_name('get-' + name_for_methods)
157 156
158 assert property_['initial_keyword'] is not None, \ 157 assert property_['initial_keyword'] is not None, \
159 ('MakeComputedStyleBase requires an initial keyword for keyword fields, none specified ' 158 ('MakeComputedStyleBase requires an initial keyword for keyword fields, none specified '
160 'for property ' + property_['name']) 159 'for property ' + property_['name'])
161 default_value = type_name + '::k' + camel_case(property_['initial_keyword']) 160 default_value = type_name + '::' + enum_value_name(property_['initial_keywor d'])
162 161
163 return Field( 162 return Field(
164 'property', 163 'property',
165 name=field_name, 164 name=class_member_name(name_for_methods),
166 property_name=property_['name'], 165 property_name=property_['name'],
167 inherited=property_['inherited'], 166 inherited=property_['inherited'],
168 independent=property_['independent'], 167 independent=property_['independent'],
169 type_name=type_name, 168 type_name=type_name,
170 field_template=property_['field_template'], 169 field_template=property_['field_template'],
171 size=int(math.ceil(bits_needed)), 170 size=int(math.ceil(bits_needed)),
172 default_value=default_value, 171 default_value=default_value,
173 getter_method_name=getter_method_name, 172 getter_method_name=getter_method_name,
174 setter_method_name='set' + property_name, 173 setter_method_name=method_name('set-' + name_for_methods),
175 initial_method_name='initial' + property_name, 174 initial_method_name=method_name('initial-' + name_for_methods),
176 resetter_method_name='reset' + property_name, 175 resetter_method_name=method_name('reset-' + name_for_methods),
177 is_inherited_method_name=property_name_lower + 'IsInherited', 176 is_inherited_method_name=method_name(name_for_methods + '-IsInherited'),
178 ) 177 )
179 178
180 179
181 def _create_inherited_flag_field(property_): 180 def _create_inherited_flag_field(property_):
182 """ 181 """
183 Create the field used for an inheritance fast path from an independent CSS p roperty, 182 Create the field used for an inheritance fast path from an independent CSS p roperty,
184 and return the Field object. 183 and return the Field object.
185 """ 184 """
186 property_name = property_['name_for_methods'] 185 name_for_methods = property_['name_for_methods']
187 property_name_lower = lower_first(property_name) 186 name_for_methods_suffixed = name_for_methods + 'IsInherited'
188
189 field_name_suffix_upper = property_name + 'IsInherited'
190 field_name_suffix_lower = property_name_lower + 'IsInherited'
191 187
192 return Field( 188 return Field(
193 'inherited_flag', 189 'inherited_flag',
194 name='m_' + field_name_suffix_lower, 190 name=class_member_name(name_for_methods_suffixed),
195 property_name=property_['name'], 191 property_name=property_['name'],
196 type_name='bool', 192 type_name='bool',
197 field_template='flag', 193 field_template='flag',
198 size=1, 194 size=1,
199 default_value='true', 195 default_value='true',
200 getter_method_name=field_name_suffix_lower, 196 getter_method_name=method_name(name_for_methods_suffixed),
201 setter_method_name='set' + field_name_suffix_upper, 197 setter_method_name=method_name('set-' + name_for_methods_suffixed),
202 initial_method_name='initial' + field_name_suffix_upper, 198 initial_method_name=method_name('initial-' + name_for_methods_suffixed),
203 resetter_method_name='reset' + field_name_suffix_upper, 199 resetter_method_name=method_name('reset-' + name_for_methods_suffixed),
204 ) 200 )
205 201
206 202
207 def _create_nonproperty_field(property_): 203 def _create_nonproperty_field(property_):
208 """ 204 """
209 Create a nonproperty field from an entry in NONPROPERTY_FIELDS and return th e Field object. 205 Create a nonproperty field from an entry in NONPROPERTY_FIELDS and return th e Field object.
210 """ 206 """
211 # TODO(shend): Make this work for nonflags 207 # TODO(shend): Make this work for nonflags
212 assert property_['field_template'] in ('flag', 'monotonic_flag', 'storage_on ly'), \ 208 assert property_['field_template'] in ('flag', 'monotonic_flag', 'storage_on ly'), \
213 "Nonproperties with arbitrary templates are not yet supported" 209 "Nonproperties with arbitrary templates are not yet supported"
214 member_name = 'm_' + property_['name'] 210 name_for_methods = property_['name_for_methods']
215 field_name_upper = upper_first_letter(property_['name'])
216 211
217 if property_['field_template'] == 'storage_only': 212 if property_['field_template'] == 'storage_only':
218 assert 'size' in property_, 'storage_only fields need to specify a size' 213 assert 'size' in property_, 'storage_only fields need to specify a size'
219 size = property_['size'] 214 size = property_['size']
220 else: 215 else:
221 # Otherwise the field must be some type of flag. 216 # Otherwise the field must be some type of flag.
222 size = 1 217 size = 1
223 218
224 return Field( 219 return Field(
225 'nonproperty', 220 'nonproperty',
226 name=member_name, 221 name=class_member_name(name_for_methods),
227 property_name=property_['name'], 222 property_name=name_for_methods,
228 type_name='bool', 223 type_name='bool',
229 field_template=property_['field_template'], 224 field_template=property_['field_template'],
230 size=size, 225 size=size,
231 default_value='false', 226 default_value='false',
232 getter_method_name=property_['name'], 227 getter_method_name=method_name(name_for_methods),
233 setter_method_name='set' + field_name_upper, 228 setter_method_name=method_name('set-' + name_for_methods),
234 initial_method_name='initial' + field_name_upper, 229 initial_method_name=method_name('initial-' + name_for_methods),
235 resetter_method_name='reset' + field_name_upper, 230 resetter_method_name=method_name('reset-' + name_for_methods),
236 ) 231 )
237 232
238 233
239 def _create_fields(properties): 234 def _create_fields(properties):
240 """ 235 """
241 Create ComputedStyle fields from CSS properties and return a list of Field o bjects. 236 Create ComputedStyle fields from CSS properties and return a list of Field o bjects.
242 """ 237 """
243 fields = [] 238 fields = []
244 for property_ in properties: 239 for property_ in properties:
245 # Only generate properties that have a field template 240 # Only generate properties that have a field template
246 if property_['field_template'] is not None: 241 if property_['field_template'] is not None:
247 # If the property is independent, add the single-bit sized isInherit ed flag 242 # If the property is independent, add the single-bit sized isInherit ed flag
248 # to the list of Fields as well. 243 # to the list of Fields as well.
249 if property_['independent']: 244 if property_['independent']:
250 fields.append(_create_inherited_flag_field(property_)) 245 fields.append(_create_inherited_flag_field(property_))
251 246
252 fields.append(_create_property_field(property_)) 247 fields.append(_create_property_field(property_))
253 248
254 # TODO(shend): Merge NONPROPERTY_FIELDS with property_values so that propert ies and 249 # TODO(shend): Merge NONPROPERTY_FIELDS with property_values so that propert ies and
255 # nonproperties can be treated uniformly. 250 # nonproperties can be treated uniformly.
256 for property_ in NONPROPERTY_FIELDS: 251 for property_ in NONPROPERTY_FIELDS:
252 property_['name_for_methods'] = property_['name']
257 fields.append(_create_nonproperty_field(property_)) 253 fields.append(_create_nonproperty_field(property_))
258 254
259 return fields 255 return fields
260 256
261 257
262 def _pack_fields(fields): 258 def _pack_fields(fields):
263 """ 259 """
264 Group a list of fields into buckets to minimise padding. 260 Group a list of fields into buckets to minimise padding.
265 Returns a list of buckets, where each bucket is a list of Field objects. 261 Returns a list of buckets, where each bucket is a list of Field objects.
266 """ 262 """
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 'expected_total_field_bytes': self._expected_total_field_bytes, 371 'expected_total_field_bytes': self._expected_total_field_bytes,
376 } 372 }
377 373
378 @template_expander.use_jinja('CSSValueIDMappingsGenerated.h.tmpl') 374 @template_expander.use_jinja('CSSValueIDMappingsGenerated.h.tmpl')
379 def generate_css_value_mappings(self): 375 def generate_css_value_mappings(self):
380 mappings = {} 376 mappings = {}
381 377
382 for property_ in self._properties.values(): 378 for property_ in self._properties.values():
383 if property_['field_template'] == 'keyword': 379 if property_['field_template'] == 'keyword':
384 mappings[property_['type_name']] = { 380 mappings[property_['type_name']] = {
385 'default_value': 'k' + camel_case(property_['initial_keyword ']), 381 'default_value': enum_value_name(property_['initial_keyword' ]),
386 'mapping': [('k' + camel_case(k), enum_for_css_keyword(k)) f or k in property_['keywords']], 382 'mapping': [(enum_value_name(k), enum_for_css_keyword(k)) fo r k in property_['keywords']],
387 } 383 }
388 384
389 return { 385 return {
390 'include_paths': self._include_paths, 386 'include_paths': self._include_paths,
391 'mappings': mappings, 387 'mappings': mappings,
392 } 388 }
393 389
394 if __name__ == '__main__': 390 if __name__ == '__main__':
395 json5_generator.Maker(ComputedStyleBaseWriter).main() 391 json5_generator.Maker(ComputedStyleBaseWriter).main()
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/build/scripts/css_properties.py ('k') | third_party/WebKit/Source/build/scripts/name_utilities.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698