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

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

Issue 2692803002: Clean up type handling in make_computed_style_base.py. (Closed)
Patch Set: Don't change behaviour Created 3 years, 10 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 19 matching lines...) Expand all
30 inherited by this style or set explicitly 30 inherited by this style or set explicitly
31 """ 31 """
32 32
33 # List of required attributes for a field which need to be passed in by 33 # List of required attributes for a field which need to be passed in by
34 # keyword arguments 34 # keyword arguments
35 REQUIRED_ATTRIBUTES = set([ 35 REQUIRED_ATTRIBUTES = set([
36 # Name of field 36 # Name of field
37 'name', 37 'name',
38 # Name of property field is for 38 # Name of property field is for
39 'property_name', 39 'property_name',
40 # Internal field storage type (storage_type_path can be None) 40 # Affects how the field is generated (keyword, primitive, external)
meade_UTC10 2017/02/13 06:46:24 How does it affect it? What are the valid values?
shend 2017/02/16 02:48:58 Added explanations in the JSON5. Made naming consi
41 'storage_type', 41 'template',
42 'storage_type_path', 42 # Path to predefined class for overriding generated types.
43 'type_path',
44 # Name of the type (e.g. EClear, int)
45 'type_name',
meade_UTC10 2017/02/13 06:46:24 Could you describe the relationship between these?
shend 2017/02/16 02:48:58 Added comment to refer readers to the JSON5 file,
43 # Bits needed for storage 46 # Bits needed for storage
44 'size', 47 'size',
45 # Default value for field 48 # Default value for field
46 'default_value', 49 'default_value',
47 # Method names 50 # Method names
48 'getter_method_name', 51 'getter_method_name',
49 'setter_method_name', 52 'setter_method_name',
50 'initial_method_name', 53 'initial_method_name',
51 'resetter_method_name', 54 'resetter_method_name',
52 ]) 55 ])
53 56
54 def __init__(self, field_family, **kwargs): 57 def __init__(self, role, **kwargs):
55 # Values common to all fields 58 # Values common to all fields
56 # Set attributes from the keyword arguments 59 # Set attributes from the keyword arguments
57 for attrib in Field.REQUIRED_ATTRIBUTES: 60 for attrib in Field.REQUIRED_ATTRIBUTES:
58 setattr(self, attrib, kwargs.pop(attrib)) 61 setattr(self, attrib, kwargs.pop(attrib))
59 62
60 # Field family: one of these must be true 63 # Field role: one of these must be true
61 self.is_property = field_family == 'property' 64 self.is_property = role == 'property'
62 self.is_inherited_flag = field_family == 'inherited_flag' 65 self.is_inherited_flag = role == 'inherited_flag'
63 assert (self.is_property, self.is_inherited_flag).count(True) == 1, \ 66 assert (self.is_property, self.is_inherited_flag).count(True) == 1, \
64 'Field family has to be exactly one of: property, inherited_flag' 67 'Field role has to be exactly one of: property, inherited_flag'
65 68
66 if self.is_property: 69 if self.is_property:
67 self.is_inherited = kwargs.pop('inherited') 70 self.is_inherited = kwargs.pop('inherited')
68 self.is_independent = kwargs.pop('independent') 71 self.is_independent = kwargs.pop('independent')
69 assert self.is_inherited or not self.is_independent, 'Only inherited fields can be independent' 72 assert self.is_inherited or not self.is_independent, 'Only inherited fields can be independent'
70 73
71 self.is_inherited_method_name = kwargs.pop('is_inherited_method_name ') 74 self.is_inherited_method_name = kwargs.pop('is_inherited_method_name ')
72 elif self.is_inherited_flag: 75 elif self.is_inherited_flag:
73 # Inherited flag-only fields 76 # Inherited flag-only fields
74 pass 77 pass
75 78
76 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st r(kwargs) 79 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st r(kwargs)
77 80
78 81
79 def _create_enums(properties): 82 def _create_enums(properties):
80 """ 83 """
81 Returns a dictionary of enums to be generated, enum name -> [list of enum va lues] 84 Returns a dictionary of enums to be generated, enum name -> [list of enum va lues]
82 """ 85 """
83 enums = {} 86 enums = {}
84 for property_ in properties: 87 for property_ in properties:
85 # Only generate enums for keyword properties that use the default field_ storage_type. 88 # Only generate enums for keyword properties that use the default field_ type_path.
86 if property_['keyword_only'] and property_['field_storage_type'] is None : 89 if property_['field_template'] == 'keyword' and property_['field_type_pa th'] is None:
87 enum_name = property_['type_name'] 90 enum_name = property_['type_name']
88 # From the Blink style guide: Enum members should use InterCaps with an initial capital letter. [names-enum-members] 91 # From the Blink style guide: Enum members should use InterCaps with an initial capital letter. [names-enum-members]
89 enum_values = [('k' + camel_case(k)) for k in property_['keywords']] 92 enum_values = [('k' + camel_case(k)) for k in property_['keywords']]
90 93
91 if enum_name in enums: 94 if enum_name in enums:
92 # There's an enum with the same name, check if the enum values a re the same 95 # There's an enum with the same name, check if the enum values a re the same
93 assert set(enums[enum_name]) == set(enum_values), \ 96 assert set(enums[enum_name]) == set(enum_values), \
94 ("'" + property_['name'] + "' can't have type_name '" + enum _name + "' " 97 ("'" + property_['name'] + "' can't have type_name '" + enum _name + "' "
95 "because it was used by a previous property, but with a dif ferent set of keywords. " 98 "because it was used by a previous property, but with a dif ferent set of keywords. "
96 "Either give it a different name or ensure the keywords are the same.") 99 "Either give it a different name or ensure the keywords are the same.")
97 100
98 enums[enum_name] = enum_values 101 enums[enum_name] = enum_values
99 102
100 return enums 103 return enums
101 104
102 105
103 def _create_property_field(property_): 106 def _create_property_field(property_):
104 """ 107 """
105 Create a property field from a CSS property and return the Field object. 108 Create a property field from a CSS property and return the Field object.
106 """ 109 """
107 property_name = property_['name_for_methods'] 110 property_name = property_['name_for_methods']
108 property_name_lower = lower_first(property_name) 111 property_name_lower = lower_first(property_name)
109 112
110 # From the Blink style guide: Other data members should be prefixed by "m_". [names-data-members] 113 # From the Blink style guide: Other data members should be prefixed by "m_". [names-data-members]
111 field_name = 'm_' + property_name_lower 114 field_name = 'm_' + property_name_lower
112 bits_needed = math.log(len(property_['keywords']), 2) 115 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for non-enums
113 116
114 # Separate the type path from the type name, if specified. 117 # Separate the type path from the type name, if specified.
115 if property_['field_storage_type']: 118 if property_['field_type_path']:
116 type_path = property_['field_storage_type'] 119 type_path = property_['field_type_path']
117 type_name = type_path.split('/')[-1] 120 type_name = type_path.split('/')[-1]
118 else: 121 else:
122 type_path = None
119 type_name = property_['type_name'] 123 type_name = property_['type_name']
120 type_path = None
121 124
122 # For now, the getter name should match the field name. Later, getter names 125 # For now, the getter name should match the field name. Later, getter names
123 # will start with an uppercase letter, so if they conflict with the type nam e, 126 # will start with an uppercase letter, so if they conflict with the type nam e,
124 # add 'get' to the front. 127 # add 'get' to the front.
125 getter_method_name = property_name_lower 128 getter_method_name = property_name_lower
126 if type_name == property_name: 129 if type_name == property_name:
127 getter_method_name = 'get' + property_name 130 getter_method_name = 'get' + property_name
128 131
129 assert property_['initial_keyword'] is not None, \ 132 assert property_['initial_keyword'] is not None, \
130 ('MakeComputedStyleBase requires an initial keyword for keyword_only val ues, none specified ' 133 ('MakeComputedStyleBase requires an initial keyword for keyword fields, none specified '
131 'for property ' + property_['name']) 134 'for property ' + property_['name'])
132 default_value = type_name + '::k' + camel_case(property_['initial_keyword']) 135 default_value = type_name + '::k' + camel_case(property_['initial_keyword'])
133 136
134 # Add the property itself as a member variable.
135 return Field( 137 return Field(
136 'property', 138 'property',
137 name=field_name, 139 name=field_name,
138 property_name=property_['name'], 140 property_name=property_['name'],
139 inherited=property_['inherited'], 141 inherited=property_['inherited'],
140 independent=property_['independent'], 142 independent=property_['independent'],
141 storage_type=type_name, 143 template=property_['field_template'],
142 storage_type_path=type_path, 144 type_path=type_path,
145 type_name=type_name,
143 size=int(math.ceil(bits_needed)), 146 size=int(math.ceil(bits_needed)),
144 default_value=default_value, 147 default_value=default_value,
145 getter_method_name=getter_method_name, 148 getter_method_name=getter_method_name,
146 setter_method_name='set' + property_name, 149 setter_method_name='set' + property_name,
147 initial_method_name='initial' + property_name, 150 initial_method_name='initial' + property_name,
148 resetter_method_name='reset' + property_name, 151 resetter_method_name='reset' + property_name,
149 is_inherited_method_name=property_name_lower + 'IsInherited', 152 is_inherited_method_name=property_name_lower + 'IsInherited',
150 ) 153 )
151 154
152 155
153 def _create_inherited_flag_field(property_): 156 def _create_inherited_flag_field(property_):
154 """ 157 """
155 Create the field used for an inheritance fast path from an independent CSS p roperty, 158 Create the field used for an inheritance fast path from an independent CSS p roperty,
156 and return the Field object. 159 and return the Field object.
157 """ 160 """
158 property_name = property_['name_for_methods'] 161 property_name = property_['name_for_methods']
159 property_name_lower = lower_first(property_name) 162 property_name_lower = lower_first(property_name)
160 163
161 field_name_suffix_upper = property_name + 'IsInherited' 164 field_name_suffix_upper = property_name + 'IsInherited'
162 field_name_suffix_lower = property_name_lower + 'IsInherited' 165 field_name_suffix_lower = property_name_lower + 'IsInherited'
163 166
164 return Field( 167 return Field(
165 'inherited_flag', 168 'inherited_flag',
166 name='m_' + field_name_suffix_lower, 169 name='m_' + field_name_suffix_lower,
167 property_name=property_['name'], 170 property_name=property_['name'],
168 storage_type='bool', 171 template='primitive',
169 storage_type_path=None, 172 type_path=None,
173 type_name='bool',
170 size=1, 174 size=1,
171 default_value='true', 175 default_value='true',
172 getter_method_name=field_name_suffix_lower, 176 getter_method_name=field_name_suffix_lower,
173 setter_method_name='set' + field_name_suffix_upper, 177 setter_method_name='set' + field_name_suffix_upper,
174 initial_method_name='initial' + field_name_suffix_upper, 178 initial_method_name='initial' + field_name_suffix_upper,
175 resetter_method_name='reset' + field_name_suffix_upper, 179 resetter_method_name='reset' + field_name_suffix_upper,
176 ) 180 )
177 181
178 182
179 def _create_fields(properties): 183 def _create_fields(properties):
180 """ 184 """
181 Create ComputedStyle fields from CSS properties and return a list of Field o bjects. 185 Create ComputedStyle fields from CSS properties and return a list of Field o bjects.
182 """ 186 """
183 fields = [] 187 fields = []
184 for property_ in properties: 188 for property_ in properties:
185 # Keywords only means we generate an enum field. 189 # Only generate properties that have a field type
186 if property_['keyword_only']: 190 if property_['field_template'] is not None:
187 # If the property is independent, add the single-bit sized isInherit ed flag 191 # If the property is independent, add the single-bit sized isInherit ed flag
188 # to the list of Fields as well. 192 # to the list of Fields as well.
189 if property_['independent']: 193 if property_['independent']:
190 fields.append(_create_inherited_flag_field(property_)) 194 fields.append(_create_inherited_flag_field(property_))
191 195
192 fields.append(_create_property_field(property_)) 196 fields.append(_create_property_field(property_))
193 197
194 return fields 198 return fields
195 199
196 200
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 def generate_base_computed_style_constants(self): 298 def generate_base_computed_style_constants(self):
295 return { 299 return {
296 'properties': self._properties, 300 'properties': self._properties,
297 'enums': self._generated_enums, 301 'enums': self._generated_enums,
298 'fields': self._fields, 302 'fields': self._fields,
299 'expected_total_field_bytes': self._expected_total_field_bytes, 303 'expected_total_field_bytes': self._expected_total_field_bytes,
300 } 304 }
301 305
302 if __name__ == '__main__': 306 if __name__ == '__main__':
303 json5_generator.Maker(ComputedStyleBaseWriter).main() 307 json5_generator.Maker(ComputedStyleBaseWriter).main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698