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 30 matching lines...) Expand all Loading... |
41 # List of required attributes for a field which need to be passed in by | 41 # List of required attributes for a field which need to be passed in by |
42 # keyword arguments. See CSSProperties.json5 for an explanation of each | 42 # keyword arguments. See CSSProperties.json5 for an explanation of each |
43 # attribute. | 43 # attribute. |
44 REQUIRED_ATTRIBUTES = set([ | 44 REQUIRED_ATTRIBUTES = set([ |
45 # Name of field | 45 # Name of field |
46 'name', | 46 'name', |
47 # Name of property field is for | 47 # Name of property field is for |
48 'property_name', | 48 'property_name', |
49 # Name of the type (e.g. EClear, int) | 49 # Name of the type (e.g. EClear, int) |
50 'type_name', | 50 'type_name', |
51 # Path to predefined class for overriding generated types. | |
52 'field_type_path', | |
53 # Affects how the field is generated (keyword, flag) | 51 # Affects how the field is generated (keyword, flag) |
54 'field_template', | 52 'field_template', |
55 # Bits needed for storage | 53 # Bits needed for storage |
56 'size', | 54 'size', |
57 # Default value for field | 55 # Default value for field |
58 'default_value', | 56 'default_value', |
59 # Method names | 57 # Method names |
60 'getter_method_name', | 58 'getter_method_name', |
61 'setter_method_name', | 59 'setter_method_name', |
62 'initial_method_name', | 60 'initial_method_name', |
(...skipping 19 matching lines...) Expand all Loading... |
82 assert self.is_inherited or not self.is_independent, 'Only inherited
fields can be independent' | 80 assert self.is_inherited or not self.is_independent, 'Only inherited
fields can be independent' |
83 | 81 |
84 self.is_inherited_method_name = kwargs.pop('is_inherited_method_name
') | 82 self.is_inherited_method_name = kwargs.pop('is_inherited_method_name
') |
85 elif self.is_inherited_flag: | 83 elif self.is_inherited_flag: |
86 # Inherited flag-only fields | 84 # Inherited flag-only fields |
87 pass | 85 pass |
88 | 86 |
89 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st
r(kwargs) | 87 assert len(kwargs) == 0, 'Unexpected arguments provided to Field: ' + st
r(kwargs) |
90 | 88 |
91 | 89 |
| 90 def _get_include_paths(properties): |
| 91 """ |
| 92 Get a list of paths that need to be included for ComputedStyleBase. |
| 93 """ |
| 94 include_paths = set() |
| 95 for property_ in properties: |
| 96 if property_['field_type_path'] is not None: |
| 97 include_paths.add(property_['field_type_path'] + '.h') |
| 98 return list(sorted(include_paths)) |
| 99 |
| 100 |
92 def _create_enums(properties): | 101 def _create_enums(properties): |
93 """ | 102 """ |
94 Returns a dictionary of enums to be generated, enum name -> [list of enum va
lues] | 103 Returns a dictionary of enums to be generated, enum name -> [list of enum va
lues] |
95 """ | 104 """ |
96 enums = {} | 105 enums = {} |
97 for property_ in properties: | 106 for property_ in properties: |
98 # Only generate enums for keyword properties that use the default field_
type_path. | 107 # Only generate enums for keyword properties that use the default field_
type_path. |
99 if property_['field_template'] == 'keyword' and property_['field_type_pa
th'] is None: | 108 if property_['field_template'] == 'keyword' and property_['field_type_pa
th'] is None: |
100 enum_name = property_['type_name'] | 109 enum_name = property_['type_name'] |
101 # From the Blink style guide: Enum members should use InterCaps with
an initial capital letter. [names-enum-members] | 110 # From the Blink style guide: Enum members should use InterCaps with
an initial capital letter. [names-enum-members] |
(...skipping 17 matching lines...) Expand all Loading... |
119 """ | 128 """ |
120 property_name = property_['name_for_methods'] | 129 property_name = property_['name_for_methods'] |
121 property_name_lower = lower_first(property_name) | 130 property_name_lower = lower_first(property_name) |
122 | 131 |
123 # From the Blink style guide: Other data members should be prefixed by "m_".
[names-data-members] | 132 # From the Blink style guide: Other data members should be prefixed by "m_".
[names-data-members] |
124 field_name = 'm_' + property_name_lower | 133 field_name = 'm_' + property_name_lower |
125 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for
non-enums | 134 bits_needed = math.log(len(property_['keywords']), 2) # TODO: implement for
non-enums |
126 | 135 |
127 # Separate the type path from the type name, if specified. | 136 # Separate the type path from the type name, if specified. |
128 if property_['field_type_path']: | 137 if property_['field_type_path']: |
129 field_type_path = property_['field_type_path'] | 138 type_name = property_['field_type_path'].split('/')[-1] |
130 type_name = field_type_path.split('/')[-1] | |
131 else: | 139 else: |
132 field_type_path = None | |
133 type_name = property_['type_name'] | 140 type_name = property_['type_name'] |
134 | 141 |
135 # For now, the getter name should match the field name. Later, getter names | 142 # For now, the getter name should match the field name. Later, getter names |
136 # will start with an uppercase letter, so if they conflict with the type nam
e, | 143 # will start with an uppercase letter, so if they conflict with the type nam
e, |
137 # add 'get' to the front. | 144 # add 'get' to the front. |
138 getter_method_name = property_name_lower | 145 getter_method_name = property_name_lower |
139 if type_name == property_name: | 146 if type_name == property_name: |
140 getter_method_name = 'get' + property_name | 147 getter_method_name = 'get' + property_name |
141 | 148 |
142 assert property_['initial_keyword'] is not None, \ | 149 assert property_['initial_keyword'] is not None, \ |
143 ('MakeComputedStyleBase requires an initial keyword for keyword fields,
none specified ' | 150 ('MakeComputedStyleBase requires an initial keyword for keyword fields,
none specified ' |
144 'for property ' + property_['name']) | 151 'for property ' + property_['name']) |
145 default_value = type_name + '::k' + camel_case(property_['initial_keyword']) | 152 default_value = type_name + '::k' + camel_case(property_['initial_keyword']) |
146 | 153 |
147 return Field( | 154 return Field( |
148 'property', | 155 'property', |
149 name=field_name, | 156 name=field_name, |
150 property_name=property_['name'], | 157 property_name=property_['name'], |
151 inherited=property_['inherited'], | 158 inherited=property_['inherited'], |
152 independent=property_['independent'], | 159 independent=property_['independent'], |
153 type_name=type_name, | 160 type_name=type_name, |
154 field_type_path=field_type_path, | |
155 field_template=property_['field_template'], | 161 field_template=property_['field_template'], |
156 size=int(math.ceil(bits_needed)), | 162 size=int(math.ceil(bits_needed)), |
157 default_value=default_value, | 163 default_value=default_value, |
158 getter_method_name=getter_method_name, | 164 getter_method_name=getter_method_name, |
159 setter_method_name='set' + property_name, | 165 setter_method_name='set' + property_name, |
160 initial_method_name='initial' + property_name, | 166 initial_method_name='initial' + property_name, |
161 resetter_method_name='reset' + property_name, | 167 resetter_method_name='reset' + property_name, |
162 is_inherited_method_name=property_name_lower + 'IsInherited', | 168 is_inherited_method_name=property_name_lower + 'IsInherited', |
163 ) | 169 ) |
164 | 170 |
165 | 171 |
166 def _create_inherited_flag_field(property_): | 172 def _create_inherited_flag_field(property_): |
167 """ | 173 """ |
168 Create the field used for an inheritance fast path from an independent CSS p
roperty, | 174 Create the field used for an inheritance fast path from an independent CSS p
roperty, |
169 and return the Field object. | 175 and return the Field object. |
170 """ | 176 """ |
171 property_name = property_['name_for_methods'] | 177 property_name = property_['name_for_methods'] |
172 property_name_lower = lower_first(property_name) | 178 property_name_lower = lower_first(property_name) |
173 | 179 |
174 field_name_suffix_upper = property_name + 'IsInherited' | 180 field_name_suffix_upper = property_name + 'IsInherited' |
175 field_name_suffix_lower = property_name_lower + 'IsInherited' | 181 field_name_suffix_lower = property_name_lower + 'IsInherited' |
176 | 182 |
177 return Field( | 183 return Field( |
178 'inherited_flag', | 184 'inherited_flag', |
179 name='m_' + field_name_suffix_lower, | 185 name='m_' + field_name_suffix_lower, |
180 property_name=property_['name'], | 186 property_name=property_['name'], |
181 type_name='bool', | 187 type_name='bool', |
182 field_type_path=None, | |
183 field_template='flag', | 188 field_template='flag', |
184 size=1, | 189 size=1, |
185 default_value='true', | 190 default_value='true', |
186 getter_method_name=field_name_suffix_lower, | 191 getter_method_name=field_name_suffix_lower, |
187 setter_method_name='set' + field_name_suffix_upper, | 192 setter_method_name='set' + field_name_suffix_upper, |
188 initial_method_name='initial' + field_name_suffix_upper, | 193 initial_method_name='initial' + field_name_suffix_upper, |
189 resetter_method_name='reset' + field_name_suffix_upper, | 194 resetter_method_name='reset' + field_name_suffix_upper, |
190 ) | 195 ) |
191 | 196 |
192 | 197 |
193 def _create_nonproperty_field(field_name): | 198 def _create_nonproperty_field(field_name): |
194 """ | 199 """ |
195 Create a nonproperty field from its name and return the Field object. | 200 Create a nonproperty field from its name and return the Field object. |
196 """ | 201 """ |
197 member_name = 'm_' + field_name | 202 member_name = 'm_' + field_name |
198 field_name_upper = upper_first_letter(field_name) | 203 field_name_upper = upper_first_letter(field_name) |
199 | 204 |
200 return Field( | 205 return Field( |
201 'nonproperty', | 206 'nonproperty', |
202 name=member_name, | 207 name=member_name, |
203 property_name=field_name, | 208 property_name=field_name, |
204 type_name='bool', | 209 type_name='bool', |
205 field_type_path=None, | |
206 field_template='flag', | 210 field_template='flag', |
207 size=1, | 211 size=1, |
208 default_value='false', | 212 default_value='false', |
209 getter_method_name=field_name, | 213 getter_method_name=field_name, |
210 setter_method_name='set' + field_name_upper, | 214 setter_method_name='set' + field_name_upper, |
211 initial_method_name='initial' + field_name_upper, | 215 initial_method_name='initial' + field_name_upper, |
212 resetter_method_name='reset' + field_name_upper, | 216 resetter_method_name='reset' + field_name_upper, |
213 ) | 217 ) |
214 | 218 |
215 | 219 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 for bucket in field_buckets: | 314 for bucket in field_buckets: |
311 for field in bucket: | 315 for field in bucket: |
312 self._fields.append(field) | 316 self._fields.append(field) |
313 | 317 |
314 | 318 |
315 @template_expander.use_jinja('ComputedStyleBase.h.tmpl') | 319 @template_expander.use_jinja('ComputedStyleBase.h.tmpl') |
316 def generate_base_computed_style_h(self): | 320 def generate_base_computed_style_h(self): |
317 return { | 321 return { |
318 'properties': self._properties, | 322 'properties': self._properties, |
319 'enums': self._generated_enums, | 323 'enums': self._generated_enums, |
| 324 'include_paths': _get_include_paths(self._properties.values()), |
320 'fields': self._fields, | 325 'fields': self._fields, |
321 'expected_total_field_bytes': self._expected_total_field_bytes, | 326 'expected_total_field_bytes': self._expected_total_field_bytes, |
322 } | 327 } |
323 | 328 |
324 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl') | 329 @template_expander.use_jinja('ComputedStyleBase.cpp.tmpl') |
325 def generate_base_computed_style_cpp(self): | 330 def generate_base_computed_style_cpp(self): |
326 return { | 331 return { |
327 'properties': self._properties, | 332 'properties': self._properties, |
328 'enums': self._generated_enums, | 333 'enums': self._generated_enums, |
329 'fields': self._fields, | 334 'fields': self._fields, |
330 'expected_total_field_bytes': self._expected_total_field_bytes, | 335 'expected_total_field_bytes': self._expected_total_field_bytes, |
331 } | 336 } |
332 | 337 |
333 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') | 338 @template_expander.use_jinja('ComputedStyleBaseConstants.h.tmpl') |
334 def generate_base_computed_style_constants(self): | 339 def generate_base_computed_style_constants(self): |
335 return { | 340 return { |
336 'properties': self._properties, | 341 'properties': self._properties, |
337 'enums': self._generated_enums, | 342 'enums': self._generated_enums, |
338 'fields': self._fields, | 343 'fields': self._fields, |
339 'expected_total_field_bytes': self._expected_total_field_bytes, | 344 'expected_total_field_bytes': self._expected_total_field_bytes, |
340 } | 345 } |
341 | 346 |
342 if __name__ == '__main__': | 347 if __name__ == '__main__': |
343 json5_generator.Maker(ComputedStyleBaseWriter).main() | 348 json5_generator.Maker(ComputedStyleBaseWriter).main() |
OLD | NEW |