OLD | NEW |
---|---|
1 #!/usr/bin/python | |
2 # | |
Nils Barth (inactive)
2013/07/09 05:04:32
For consistency, add executable if runs 'main()'
(
| |
1 # Copyright (C) 2013 Google Inc. All rights reserved. | 3 # Copyright (C) 2013 Google Inc. All rights reserved. |
2 # | 4 # |
3 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
5 # met: | 7 # met: |
6 # | 8 # |
7 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 11 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 12 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 15 matching lines...) Expand all Loading... | |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | 30 |
29 import optparse | 31 import optparse |
30 import os | 32 import os |
31 import os.path | 33 import os.path |
32 import re | 34 import re |
33 import string | 35 import string |
34 | 36 |
35 | 37 |
38 class IdlBadFilenameError(Exception): | |
39 """Raised if an IDL filename disagrees with the interface name in the file." "" | |
40 pass | |
41 | |
42 | |
43 class IdlInterfaceFileNotFoundError(Exception): | |
44 """Raised if the IDL file implementing an interface cannot be found.""" | |
45 pass | |
46 | |
47 | |
36 def parse_options(): | 48 def parse_options(): |
37 parser = optparse.OptionParser() | 49 parser = optparse.OptionParser() |
38 parser.add_option('--event-names-file', help='output file') | 50 parser.add_option('--event-names-file', help='output file') |
39 parser.add_option('--idl-files-list', help='file listing all IDLs') | 51 parser.add_option('--idl-files-list', help='file listing all IDLs') |
40 parser.add_option('--supplemental-dependency-file', help='output file') | 52 parser.add_option('--interface-dependencies-file', help='output file') |
41 parser.add_option('--window-constructors-file', help='output file') | 53 parser.add_option('--window-constructors-file', help='output file') |
42 parser.add_option('--workerglobalscope-constructors-file', help='output file ') | 54 parser.add_option('--workerglobalscope-constructors-file', help='output file ') |
43 parser.add_option('--sharedworkerglobalscope-constructors-file', help='outpu t file') | 55 parser.add_option('--sharedworkerglobalscope-constructors-file', help='outpu t file') |
44 parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='ou tput file') | 56 parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='ou tput file') |
45 parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja') | 57 parser.add_option('--write-file-only-if-changed', type='int', help='if true, do not write an output file if it would be identical to the existing one, which avoids unnecessary rebuilds in ninja') |
46 options, args = parser.parse_args() | 58 options, args = parser.parse_args() |
47 if options.event_names_file is None: | 59 if options.event_names_file is None: |
48 parser.error('Must specify an output file using --event-names-file.') | 60 parser.error('Must specify an output file using --event-names-file.') |
49 if options.supplemental_dependency_file is None: | 61 if options.interface_dependencies_file is None: |
50 parser.error('Must specify an output file using --supplemental-dependenc y-file.') | 62 parser.error('Must specify an output file using --interface-dependencies -file.') |
51 if options.window_constructors_file is None: | 63 if options.window_constructors_file is None: |
52 parser.error('Must specify an output file using --window-constructors-fi le.') | 64 parser.error('Must specify an output file using --window-constructors-fi le.') |
53 if options.workerglobalscope_constructors_file is None: | 65 if options.workerglobalscope_constructors_file is None: |
54 parser.error('Must specify an output file using --workerglobalscope-cons tructors-file.') | 66 parser.error('Must specify an output file using --workerglobalscope-cons tructors-file.') |
55 if options.workerglobalscope_constructors_file is None: | 67 if options.workerglobalscope_constructors_file is None: |
56 parser.error('Must specify an output file using --sharedworkerglobalscop e-constructors-file.') | 68 parser.error('Must specify an output file using --sharedworkerglobalscop e-constructors-file.') |
57 if options.workerglobalscope_constructors_file is None: | 69 if options.workerglobalscope_constructors_file is None: |
58 parser.error('Must specify an output file using --dedicatedworkerglobals cope-constructors-file.') | 70 parser.error('Must specify an output file using --dedicatedworkerglobals cope-constructors-file.') |
59 if options.idl_files_list is None: | 71 if options.idl_files_list is None: |
60 parser.error('Must specify the file listing all IDLs using --idl-files-l ist.') | 72 parser.error('Must specify the file listing all IDLs using --idl-files-l ist.') |
(...skipping 27 matching lines...) Expand all Loading... | |
88 return match.group(1) | 100 return match.group(1) |
89 return None | 101 return None |
90 | 102 |
91 | 103 |
92 # identifier-A implements identifier-B; | 104 # identifier-A implements identifier-B; |
93 # http://www.w3.org/TR/WebIDL/#idl-implements-statements | 105 # http://www.w3.org/TR/WebIDL/#idl-implements-statements |
94 def get_implemented_interfaces_from_idl(file_contents, interface_name): | 106 def get_implemented_interfaces_from_idl(file_contents, interface_name): |
95 implemented_interfaces = [] | 107 implemented_interfaces = [] |
96 for match in re.finditer(r'^\s*(\w+)\s+implements\s+(\w+)\s*;', file_content s, re.MULTILINE): | 108 for match in re.finditer(r'^\s*(\w+)\s+implements\s+(\w+)\s*;', file_content s, re.MULTILINE): |
97 # identifier-A must be the current interface | 109 # identifier-A must be the current interface |
98 assert match.group(1) == interface_name, \ | 110 if match.group(1) != interface_name: |
99 "Identifier on the left of the 'implements' statement should be %s in %s.idl, bu t found %s" % (interface_name, interface_name, match.group(1)) | 111 raise IdlBadFilenameError("Identifier on the left of the 'implements ' statement should be %s in %s.idl, but found %s" % (interface_name, interface_n ame, match.group(1))) |
Nils Barth (inactive)
2013/07/09 05:04:32
"assert" is only for internal consistency (debug s
| |
100 implemented_interfaces.append(match.group(2)) | 112 implemented_interfaces.append(match.group(2)) |
101 return implemented_interfaces | 113 return implemented_interfaces |
102 | 114 |
115 | |
103 def is_callback_interface_from_idl(file_contents): | 116 def is_callback_interface_from_idl(file_contents): |
104 match = re.search(r'callback\s+interface\s+\w+', file_contents) | 117 match = re.search(r'callback\s+interface\s+\w+', file_contents) |
105 return match is not None | 118 return match is not None |
106 | 119 |
107 | 120 |
108 def get_parent_interface(file_contents): | 121 def get_parent_interface(file_contents): |
109 match = re.search(r'interface\s+\w+\s*:\s*(\w+)\s*', file_contents) | 122 match = re.search(r'interface\s+\w+\s*:\s*(\w+)\s*', file_contents) |
110 if match: | 123 if match: |
111 return match.group(1) | 124 return match.group(1) |
112 return None | 125 return None |
113 | 126 |
127 | |
114 def get_interface_extended_attributes_from_idl(file_contents): | 128 def get_interface_extended_attributes_from_idl(file_contents): |
115 extended_attributes = {} | 129 extended_attributes = {} |
116 match = re.search(r'\[(.*)\]\s+(interface|exception)\s+(\w+)', | 130 match = re.search(r'\[(.*)\]\s+(callback\s+)?(interface|exception)\s+(\w+)', |
117 file_contents, flags=re.DOTALL) | 131 file_contents, flags=re.DOTALL) |
118 if match: | 132 if match: |
119 parts = string.split(match.group(1), ',') | 133 parts = string.split(match.group(1), ',') |
120 for part in parts: | 134 for part in parts: |
121 # Match 'key = value' | 135 key, _, value = map(string.strip, part.partition('=')) |
122 match = re.match(r'([^=\s]*)(?:\s*=\s*(.*))?', part.strip()) | |
123 key = match.group(1) | |
124 value = match.group(2) or 'VALUE_IS_MISSING' | |
Nils Barth (inactive)
2013/07/09 05:04:32
str.partition() does exactly what we want - no nee
| |
125 if not key: | 136 if not key: |
126 continue | 137 continue |
138 value = value or 'VALUE_IS_MISSING' | |
127 extended_attributes[key] = value | 139 extended_attributes[key] = value |
128 return extended_attributes | 140 return extended_attributes |
129 | 141 |
130 | 142 |
131 def generate_constructor_attribute_list(interface_name, extended_attributes): | 143 def generate_constructor_attribute_list(interface_name, extended_attributes): |
132 extended_attributes_list = [] | 144 extended_attributes_list = [] |
133 for attribute_name, attribute_value in extended_attributes.iteritems(): | 145 for attribute_name, attribute_value in extended_attributes.iteritems(): |
134 if attribute_name not in ['Conditional', 'EnabledAtRuntime', 'EnabledPer Context']: | 146 if attribute_name not in ['Conditional', 'EnabledAtRuntime', 'EnabledPer Context']: |
135 continue | 147 continue |
136 extended_attribute = attribute_name | 148 extended_attribute = attribute_name |
(...skipping 15 matching lines...) Expand all Loading... | |
152 named_constructor = extended_attributes['NamedConstructor'] | 164 named_constructor = extended_attributes['NamedConstructor'] |
153 # Extract function name, namely everything before opening '(' | 165 # Extract function name, namely everything before opening '(' |
154 constructor_name = re.sub(r'\(.*', '', named_constructor) | 166 constructor_name = re.sub(r'\(.*', '', named_constructor) |
155 # Note the reduplicated 'ConstructorConstructor' | 167 # Note the reduplicated 'ConstructorConstructor' |
156 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name) | 168 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name) |
157 attributes_list.append(extended_string + attribute_string) | 169 attributes_list.append(extended_string + attribute_string) |
158 | 170 |
159 return attributes_list | 171 return attributes_list |
160 | 172 |
161 | 173 |
162 def generate_event_names_file(destination_filename, event_names, only_if_changed =False): | 174 def generate_event_names_file(destination_filename, event_names, only_if_changed ): |
Nils Barth (inactive)
2013/07/09 05:04:32
only_if_changed is really important and omitting i
| |
163 source_dir, _ = os.path.split(os.getcwd()) | 175 source_dir, _ = os.path.split(os.getcwd()) |
164 lines = [] | 176 lines = [] |
165 lines.append('namespace="Event"\n') | 177 lines.append('namespace="Event"\n') |
166 lines.append('\n') | 178 lines.append('\n') |
167 for filename in event_names: | 179 for filename, extended_attributes in sorted(event_names.iteritems()): |
Nils Barth (inactive)
2013/07/09 05:04:32
More sorting for consistency (below too).
| |
168 attributes = [] | 180 attributes = [] |
169 extended_attributes = event_names[filename] | |
170 for key in ('ImplementedAs', 'Conditional', 'EnabledAtRuntime'): | 181 for key in ('ImplementedAs', 'Conditional', 'EnabledAtRuntime'): |
171 suffix = '' | 182 suffix = '' |
172 if key == 'EnabledAtRuntime': | 183 if key == 'EnabledAtRuntime': |
173 suffix = 'Enabled' | 184 suffix = 'Enabled' |
174 if key in extended_attributes: | 185 if key in extended_attributes: |
175 attributes.append('%s=%s%s' % (key, extended_attributes[key], su ffix)) | 186 attributes.append('%s=%s%s' % (key, extended_attributes[key], su ffix)) |
176 refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_ dir)) | 187 refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_ dir)) |
177 lines.append('%s %s\n' % (refined_filename, ', '.join(attributes))) | 188 lines.append('%s %s\n' % (refined_filename, ', '.join(attributes))) |
178 write_file(lines, destination_filename, only_if_changed) | 189 write_file(lines, destination_filename, only_if_changed) |
179 | 190 |
180 | 191 |
181 def generate_global_constructors_partial_interface(interface_name, destination_f ilename, constructor_attributes_list, only_if_changed=False): | 192 def generate_global_constructors_partial_interface(interface_name, destination_f ilename, constructor_attributes_list, only_if_changed): |
182 lines = [] | 193 lines = [] |
183 lines.append('partial interface %s {\n' % interface_name) | 194 lines.append('partial interface %s {\n' % interface_name) |
184 for constructor_attribute in constructor_attributes_list: | 195 for constructor_attribute in constructor_attributes_list: |
185 lines.append(' %s;\n' % constructor_attribute) | 196 lines.append(' %s;\n' % constructor_attribute) |
186 lines.append('};\n') | 197 lines.append('};\n') |
187 write_file(lines, destination_filename, only_if_changed) | 198 write_file(lines, destination_filename, only_if_changed) |
188 | 199 |
189 | 200 |
190 def parse_idl_files(idl_files, window_constructors_filename, workerglobalscope_c onstructors_filename, sharedworkerglobalscope_constructors_filename, dedicatedwo rkerglobalscope_constructors_filename, event_names_file, only_if_changed=False): | 201 def parse_idl_files(idl_files, global_constructors_filenames): |
Nils Barth (inactive)
2013/07/09 05:04:32
This is the main content of this CL.
Other than so
| |
191 interface_name_to_idl_file = {} | 202 """Returns dependencies between IDL files, global interfaces, and events. |
haraken
2013/07/09 05:21:38
Nit: global interfaces => constructors on global o
Nils Barth (inactive)
2013/07/09 06:00:40
Got it, changed here and throughout!
(I wasn't ter
| |
192 idl_file_to_interface_name = {} | |
Nils Barth (inactive)
2013/07/09 05:04:32
idl_file_to_interface_name: unused, removed
| |
193 supplemental_dependencies = {} | |
194 supplementals = {} | |
Nils Barth (inactive)
2013/07/09 05:04:32
supplemental_dependencies/supplementals are confus
| |
195 event_names = {} | |
196 window_constructor_attributes_list = [] | |
197 workerglobalscope_constructor_attributes_list = [] | |
198 sharedworkerglobalscope_constructor_attributes_list = [] | |
199 dedicatedworkerglobalscope_constructor_attributes_list = [] | |
200 | 203 |
204 Returns: | |
205 interfaces: | |
206 set of all interfaces | |
207 dependencies: | |
208 dict of main IDL filename (for a given interface) -> list of partial IDL filenames (for that interface) | |
209 The keys (main IDL files) are the files for which bindings are | |
210 generated. This does not include IDL files for interfaces | |
211 implemented by another interface. | |
212 global_constructor_attributes: | |
213 dict of global interfaces -> list of attributes in that interface | |
haraken
2013/07/09 05:21:38
Ditto.
| |
214 event_names: | |
215 dict of interfaces that inherit from Event -> list of extended attri butes for the interface | |
216 """ | |
217 interfaces = set() | |
218 dependencies = {} | |
219 partial_interface_files = {} | |
220 implements_interfaces = {} | |
221 implemented_somewhere = set() | |
222 | |
223 global_constructor_attributes = {} | |
224 for global_interface in global_constructors_filenames.keys(): | |
225 global_constructor_attributes[global_interface] = [] | |
226 | |
227 # Parents and extended attributes (of interfaces with parents) are | |
228 # used in generating event names | |
201 parent_interface = {} | 229 parent_interface = {} |
202 interface_extended_attribute = {} | 230 interface_extended_attribute = {} |
203 interface_to_file = {} | |
Nils Barth (inactive)
2013/07/09 05:04:32
Redundant with interface_name_to_idl_file, removed
| |
204 | 231 |
205 # Populate interface_name_to_idl_file first | 232 interface_name_to_idl_file = {} |
206 for idl_file_name in idl_files: | 233 for idl_file_name in idl_files: |
207 full_path = os.path.realpath(idl_file_name) | 234 full_path = os.path.realpath(idl_file_name) |
208 interface_name, _ = os.path.splitext(os.path.basename(idl_file_name)) | 235 interface_name, _ = os.path.splitext(os.path.basename(idl_file_name)) |
209 interface_name_to_idl_file[interface_name] = full_path | 236 interface_name_to_idl_file[interface_name] = full_path |
237 partial_interface_files[interface_name] = [] | |
210 | 238 |
211 for idl_file_name in idl_files: | 239 for idl_file_name in idl_files: |
212 full_path = os.path.realpath(idl_file_name) | |
213 interface_name, _ = os.path.splitext(os.path.basename(idl_file_name)) | 240 interface_name, _ = os.path.splitext(os.path.basename(idl_file_name)) |
241 full_path = interface_name_to_idl_file[interface_name] | |
214 idl_file_contents = get_file_contents(full_path) | 242 idl_file_contents = get_file_contents(full_path) |
215 | 243 |
216 if interface_name == 'Event': | |
217 event_names[idl_file_name] = get_interface_extended_attributes_from_ idl(idl_file_contents) | |
218 else: | |
219 parent = get_parent_interface(idl_file_contents) | |
220 if parent: | |
221 parent_interface[interface_name] = parent | |
222 interface_extended_attribute[interface_name] = get_interface_ext ended_attributes_from_idl(idl_file_contents) | |
223 interface_to_file[interface_name] = idl_file_name | |
224 | |
225 # Handle partial interfaces | 244 # Handle partial interfaces |
226 partial_interface_name = get_partial_interface_name_from_idl(idl_file_co ntents) | 245 partial_interface_name = get_partial_interface_name_from_idl(idl_file_co ntents) |
227 if partial_interface_name: | 246 if partial_interface_name: |
228 supplemental_dependencies[full_path] = [partial_interface_name] | 247 partial_interface_files[partial_interface_name].append(full_path) |
229 continue | 248 continue |
230 | 249 |
231 # Parse 'identifier-A implements identifier-B; statements | 250 interfaces.add(interface_name) |
251 # Non-partial interfaces default to having bindings generated | |
252 dependencies[full_path] = [] | |
253 extended_attributes = get_interface_extended_attributes_from_idl(idl_fil e_contents) | |
254 | |
255 # Parse 'identifier-A implements identifier-B;' statements | |
232 implemented_interfaces = get_implemented_interfaces_from_idl(idl_file_co ntents, interface_name) | 256 implemented_interfaces = get_implemented_interfaces_from_idl(idl_file_co ntents, interface_name) |
233 for implemented_interface in implemented_interfaces: | 257 implements_interfaces[interface_name] = implemented_interfaces |
234 assert implemented_interface in interface_name_to_idl_file, \ | 258 implemented_somewhere |= set(implemented_interfaces) |
235 "Could not find a the IDL file where the following implemented interface is defi ned: %s" % implemented_interface | |
236 supplemental_dependencies.setdefault(interface_name_to_idl_file[impl emented_interface], []).append(interface_name) | |
237 # Handle [NoInterfaceObject] | |
238 if not is_callback_interface_from_idl(idl_file_contents): | |
239 extended_attributes = get_interface_extended_attributes_from_idl(idl _file_contents) | |
240 if 'NoInterfaceObject' not in extended_attributes: | |
241 global_contexts = extended_attributes.get('GlobalContext', 'Wind ow').split('&') | |
242 constructor_list = generate_constructor_attribute_list(interface _name, extended_attributes) | |
243 if 'Window' in global_contexts: | |
244 window_constructor_attributes_list.extend(constructor_list) | |
245 if 'WorkerGlobalScope' in global_contexts: | |
246 workerglobalscope_constructor_attributes_list.extend(constru ctor_list) | |
247 if 'SharedWorkerGlobalScope' in global_contexts: | |
248 sharedworkerglobalscope_constructor_attributes_list.extend(c onstructor_list) | |
249 if 'DedicatedWorkerGlobalScope' in global_contexts: | |
250 dedicatedworkerglobalscope_constructor_attributes_list.exten d(constructor_list) | |
251 idl_file_to_interface_name[full_path] = interface_name | |
252 supplementals[full_path] = [] | |
253 | 259 |
254 for interface in parent_interface: | 260 # Record global constructor attributes |
255 parent = parent_interface[interface] | 261 if not is_callback_interface_from_idl(idl_file_contents) and 'NoInterfac eObject' not in extended_attributes: |
262 global_contexts = extended_attributes.get('GlobalContext', 'Window') .split('&') | |
263 constructor_list = generate_constructor_attribute_list(interface_nam e, extended_attributes) | |
264 for global_interface, attribute_list in global_constructor_attribute s.iteritems(): | |
265 if global_interface in global_contexts: | |
266 attribute_list.extend(constructor_list) | |
Nils Barth (inactive)
2013/07/09 06:00:40
One more minor cleanup.
| |
267 | |
268 # Record parents and extended attributes for generating event names | |
269 if interface_name == 'Event': | |
270 interface_extended_attribute[interface_name] = extended_attributes | |
271 parent = get_parent_interface(idl_file_contents) | |
272 if parent: | |
273 parent_interface[interface_name] = parent | |
274 interface_extended_attribute[interface_name] = extended_attributes | |
275 | |
276 # Add global constructors to partial interfaces | |
277 for global_interface, filename in global_constructors_filenames.iteritems(): | |
278 if global_interface in interfaces: | |
279 partial_interface_files[global_interface].append(filename) | |
280 | |
281 # Interfaces that are implemented by another interface do not have | |
282 # their own bindings generated, as this would be redundant with the | |
283 # actual implementation. | |
284 for implemented_interface in implemented_somewhere: | |
285 full_path = interface_name_to_idl_file[implemented_interface] | |
286 del dependencies[full_path] | |
287 | |
288 # An IDL file's dependencies are partial interface files that extend it, | |
289 # and files for other interfaces that this interfaces implements. | |
290 for idl_file_path, others in dependencies.iteritems(): | |
291 interface_name, _ = os.path.splitext(os.path.basename(idl_file_path)) | |
292 implemented_interfaces = implements_interfaces[interface_name] | |
293 try: | |
294 interface_paths = map(lambda x: interface_name_to_idl_file[x], imple mented_interfaces) | |
295 except KeyError, key_name: | |
296 raise IdlInterfaceFileNotFoundError('Could not find the IDL file whe re the following implemented interface is defined: %s' % key_name) | |
297 dependencies[idl_file_path] = sorted(partial_interface_files[interface_n ame] + interface_paths) | |
298 | |
299 # Generate event names for all interfaces that inherit from Event, | |
300 # including Event itself. | |
301 event_names = {} | |
302 if 'Event' in interfaces: | |
303 event_names[interface_name_to_idl_file['Event']] = interface_extended_at tribute['Event'] | |
304 for interface, parent in parent_interface.iteritems(): | |
256 while parent in parent_interface: | 305 while parent in parent_interface: |
257 parent = parent_interface[parent] | 306 parent = parent_interface[parent] |
258 if parent == 'Event': | 307 if parent == 'Event': |
259 event_names[interface_to_file[interface]] = interface_extended_attri bute[interface] | 308 event_names[interface_name_to_idl_file[interface]] = interface_exten ded_attribute[interface] |
260 generate_event_names_file(event_names_file, event_names, only_if_changed=onl y_if_changed) | |
261 | 309 |
262 # Generate Global constructors | 310 return interfaces, dependencies, global_constructor_attributes, event_names |
263 if 'Window' in interface_name_to_idl_file: | |
264 generate_global_constructors_partial_interface("Window", window_construc tors_filename, window_constructor_attributes_list, only_if_changed=only_if_chang ed) | |
Nils Barth (inactive)
2013/07/09 05:04:32
This mixes generating output files with parsing th
| |
265 supplemental_dependencies[window_constructors_filename] = ['Window'] | |
266 if 'WorkerGlobalScope' in interface_name_to_idl_file: | |
267 generate_global_constructors_partial_interface("WorkerGlobalScope", work erglobalscope_constructors_filename, workerglobalscope_constructor_attributes_li st, only_if_changed=only_if_changed) | |
268 supplemental_dependencies[workerglobalscope_constructors_filename] = ['W orkerGlobalScope'] | |
269 if 'SharedWorkerGlobalScope' in interface_name_to_idl_file: | |
270 generate_global_constructors_partial_interface("SharedWorkerGlobalScope" , sharedworkerglobalscope_constructors_filename, sharedworkerglobalscope_constru ctor_attributes_list, only_if_changed=only_if_changed) | |
271 supplemental_dependencies[sharedworkerglobalscope_constructors_filename] = ['SharedWorkerGlobalScope'] | |
272 if 'DedicatedWorkerGlobalScope' in interface_name_to_idl_file: | |
273 generate_global_constructors_partial_interface("DedicatedWorkerGlobalSco pe", dedicatedworkerglobalscope_constructors_filename, dedicatedworkerglobalscop e_constructor_attributes_list, only_if_changed=only_if_changed) | |
274 supplemental_dependencies[dedicatedworkerglobalscope_constructors_filena me] = ['DedicatedWorkerGlobalScope'] | |
275 | |
276 # Resolve partial interfaces dependencies | |
277 for idl_file, base_files in supplemental_dependencies.iteritems(): | |
278 for base_file in base_files: | |
279 target_idl_file = interface_name_to_idl_file[base_file] | |
280 supplementals[target_idl_file].append(idl_file) | |
281 if idl_file in supplementals: | |
282 # Should never occur. Might be needed in corner cases. | |
283 del supplementals[idl_file] | |
Nils Barth (inactive)
2013/07/09 05:04:32
This 'del' was originally for circular dependencie
| |
284 return supplementals | |
285 | 311 |
286 | 312 |
287 def write_dependency_file(filename, supplementals, only_if_changed=False): | 313 def write_dependency_file(filename, dependencies, only_if_changed): |
288 """Outputs the dependency file. | 314 """Writes the interface dependencies file. |
289 | 315 |
290 The format of a supplemental dependency file: | 316 The format is as follows: |
291 | 317 |
292 Window.idl P.idl Q.idl R.idl | 318 Window.idl P.idl Q.idl R.idl |
293 Document.idl S.idl | 319 Document.idl S.idl |
294 Event.idl | 320 Event.idl |
295 ... | 321 ... |
296 | 322 |
297 The above indicates that: | 323 The above indicates that: |
298 Window.idl is supplemented by P.idl, Q.idl and R.idl, | 324 Window.idl depends on P.idl, Q.idl, and R.idl, |
299 Document.idl is supplemented by S.idl, and | 325 Document.idl depends on S.idl, and |
300 Event.idl is supplemented by no IDLs. | 326 Event.idl depends on no other IDL files. |
301 | 327 |
302 An IDL that supplements another IDL (e.g. P.idl) does not have its own | 328 An IDL that supplements another IDL (e.g. P.idl) does not have its own |
303 lines in the dependency file. | 329 lines in the dependency file. |
304 """ | 330 """ |
305 lines = [] | 331 lines = [] |
306 for idl_file, supplemental_files in sorted(supplementals.iteritems()): | 332 for idl_file, dependency_files in sorted(dependencies.iteritems()): |
307 lines.append('%s %s\n' % (idl_file, ' '.join(supplemental_files))) | 333 lines.append('%s %s\n' % (idl_file, ' '.join(sorted(dependency_files)))) |
308 write_file(lines, filename, only_if_changed) | 334 write_file(lines, filename, only_if_changed) |
309 | 335 |
310 | 336 |
311 def main(): | 337 def main(): |
312 options = parse_options() | 338 options = parse_options() |
313 idl_files = [] | 339 idl_files = [] |
314 with open(options.idl_files_list) as idl_files_list_file: | 340 with open(options.idl_files_list) as idl_files_list_file: |
315 for line in idl_files_list_file: | 341 for line in idl_files_list_file: |
316 idl_files.append(string.rstrip(line, '\n')) | 342 idl_files.append(string.rstrip(line, '\n')) |
317 resolved_supplementals = parse_idl_files(idl_files, options.window_construct ors_file, options.workerglobalscope_constructors_file, options.sharedworkergloba lscope_constructors_file, options.dedicatedworkerglobalscope_constructors_file, options.event_names_file, only_if_changed=options.write_file_only_if_changed) | 343 only_if_changed = options.write_file_only_if_changed |
318 write_dependency_file(options.supplemental_dependency_file, resolved_supplem entals, only_if_changed=options.write_file_only_if_changed) | 344 global_constructors_filenames = { |
345 'Window': options.window_constructors_file, | |
346 'WorkerGlobalScope': options.workerglobalscope_constructors_file, | |
347 'SharedWorkerGlobalScope': options.sharedworkerglobalscope_constructors_ file, | |
348 'DedicatedWorkerGlobalScope': options.dedicatedworkerglobalscope_constru ctors_file, | |
349 } | |
350 | |
351 interfaces, dependencies, global_constructor_attributes, event_names = parse _idl_files(idl_files, global_constructors_filenames) | |
352 | |
353 write_dependency_file(options.interface_dependencies_file, dependencies, onl y_if_changed) | |
354 for interface_name, filename in global_constructors_filenames.iteritems(): | |
355 if interface_name in interfaces: | |
356 generate_global_constructors_partial_interface(interface_name, filen ame, global_constructor_attributes[interface_name], only_if_changed) | |
357 generate_event_names_file(options.event_names_file, event_names, options.wri te_file_only_if_changed) | |
Nils Barth (inactive)
2013/07/09 05:04:32
Write all the files in one place.
| |
319 | 358 |
320 | 359 |
321 if __name__ == '__main__': | 360 if __name__ == '__main__': |
322 main() | 361 main() |
OLD | NEW |