OLD | NEW |
| 1 #!/usr/bin/python |
| 2 # |
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))) |
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' | |
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
): |
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()): |
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): |
191 interface_name_to_idl_file = {} | 202 """Returns dependencies between IDL files, constructors on global objects, a
nd events. |
192 idl_file_to_interface_name = {} | |
193 supplemental_dependencies = {} | |
194 supplementals = {} | |
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_constructors: |
| 213 dict of global objects -> list of constructors on that object |
| 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_constructors = {} |
| 224 for global_object in global_constructors_filenames.keys(): |
| 225 global_constructors[global_object] = [] |
| 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 = {} | |
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 constructors |
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 new_constructor_list = generate_constructor_attribute_list(interface
_name, extended_attributes) |
| 264 for global_object in global_contexts: |
| 265 global_constructors[global_object].extend(new_constructor_list) |
| 266 |
| 267 # Record parents and extended attributes for generating event names |
| 268 if interface_name == 'Event': |
| 269 interface_extended_attribute[interface_name] = extended_attributes |
| 270 parent = get_parent_interface(idl_file_contents) |
| 271 if parent: |
| 272 parent_interface[interface_name] = parent |
| 273 interface_extended_attribute[interface_name] = extended_attributes |
| 274 |
| 275 # Add constructors on global objects to partial interfaces |
| 276 for global_object, filename in global_constructors_filenames.iteritems(): |
| 277 if global_object in interfaces: |
| 278 partial_interface_files[global_object].append(filename) |
| 279 |
| 280 # Interfaces that are implemented by another interface do not have |
| 281 # their own bindings generated, as this would be redundant with the |
| 282 # actual implementation. |
| 283 for implemented_interface in implemented_somewhere: |
| 284 full_path = interface_name_to_idl_file[implemented_interface] |
| 285 del dependencies[full_path] |
| 286 |
| 287 # An IDL file's dependencies are partial interface files that extend it, |
| 288 # and files for other interfaces that this interfaces implements. |
| 289 for idl_file_path, others in dependencies.iteritems(): |
| 290 interface_name, _ = os.path.splitext(os.path.basename(idl_file_path)) |
| 291 implemented_interfaces = implements_interfaces[interface_name] |
| 292 try: |
| 293 interface_paths = map(lambda x: interface_name_to_idl_file[x], imple
mented_interfaces) |
| 294 except KeyError, key_name: |
| 295 raise IdlInterfaceFileNotFoundError('Could not find the IDL file whe
re the following implemented interface is defined: %s' % key_name) |
| 296 dependencies[idl_file_path] = sorted(partial_interface_files[interface_n
ame] + interface_paths) |
| 297 |
| 298 # Generate event names for all interfaces that inherit from Event, |
| 299 # including Event itself. |
| 300 event_names = {} |
| 301 if 'Event' in interfaces: |
| 302 event_names[interface_name_to_idl_file['Event']] = interface_extended_at
tribute['Event'] |
| 303 for interface, parent in parent_interface.iteritems(): |
256 while parent in parent_interface: | 304 while parent in parent_interface: |
257 parent = parent_interface[parent] | 305 parent = parent_interface[parent] |
258 if parent == 'Event': | 306 if parent == 'Event': |
259 event_names[interface_to_file[interface]] = interface_extended_attri
bute[interface] | 307 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 | 308 |
262 # Generate Global constructors | 309 return interfaces, dependencies, global_constructors, 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) | |
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] | |
284 return supplementals | |
285 | 310 |
286 | 311 |
287 def write_dependency_file(filename, supplementals, only_if_changed=False): | 312 def write_dependency_file(filename, dependencies, only_if_changed): |
288 """Outputs the dependency file. | 313 """Writes the interface dependencies file. |
289 | 314 |
290 The format of a supplemental dependency file: | 315 The format is as follows: |
291 | 316 |
292 Window.idl P.idl Q.idl R.idl | 317 Document.idl P.idl |
293 Document.idl S.idl | |
294 Event.idl | 318 Event.idl |
| 319 Window.idl Q.idl R.idl S.idl |
295 ... | 320 ... |
296 | 321 |
297 The above indicates that: | 322 The above indicates that: |
298 Window.idl is supplemented by P.idl, Q.idl and R.idl, | 323 Document.idl depends on P.idl, |
299 Document.idl is supplemented by S.idl, and | 324 Event.idl depends on no other IDL files, and |
300 Event.idl is supplemented by no IDLs. | 325 Window.idl depends on Q.idl, R.idl, and S.idl. |
301 | 326 |
302 An IDL that supplements another IDL (e.g. P.idl) does not have its own | 327 An IDL that is a dependency of another IDL (e.g. P.idl) does not have its |
303 lines in the dependency file. | 328 own line in the dependency file. |
304 """ | 329 """ |
305 lines = [] | 330 lines = [] |
306 for idl_file, supplemental_files in sorted(supplementals.iteritems()): | 331 for idl_file, dependency_files in sorted(dependencies.iteritems()): |
307 lines.append('%s %s\n' % (idl_file, ' '.join(supplemental_files))) | 332 lines.append('%s %s\n' % (idl_file, ' '.join(sorted(dependency_files)))) |
308 write_file(lines, filename, only_if_changed) | 333 write_file(lines, filename, only_if_changed) |
309 | 334 |
310 | 335 |
311 def main(): | 336 def main(): |
312 options = parse_options() | 337 options = parse_options() |
313 idl_files = [] | 338 idl_files = [] |
314 with open(options.idl_files_list) as idl_files_list_file: | 339 with open(options.idl_files_list) as idl_files_list_file: |
315 for line in idl_files_list_file: | 340 for line in idl_files_list_file: |
316 idl_files.append(string.rstrip(line, '\n')) | 341 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) | 342 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) | 343 global_constructors_filenames = { |
| 344 'Window': options.window_constructors_file, |
| 345 'WorkerGlobalScope': options.workerglobalscope_constructors_file, |
| 346 'SharedWorkerGlobalScope': options.sharedworkerglobalscope_constructors_
file, |
| 347 'DedicatedWorkerGlobalScope': options.dedicatedworkerglobalscope_constru
ctors_file, |
| 348 } |
| 349 |
| 350 interfaces, dependencies, global_constructors, event_names = parse_idl_files
(idl_files, global_constructors_filenames) |
| 351 |
| 352 write_dependency_file(options.interface_dependencies_file, dependencies, onl
y_if_changed) |
| 353 for interface_name, filename in global_constructors_filenames.iteritems(): |
| 354 if interface_name in interfaces: |
| 355 generate_global_constructors_partial_interface(interface_name, filen
ame, global_constructors[interface_name], only_if_changed) |
| 356 generate_event_names_file(options.event_names_file, event_names, only_if_cha
nged) |
319 | 357 |
320 | 358 |
321 if __name__ == '__main__': | 359 if __name__ == '__main__': |
322 main() | 360 main() |
OLD | NEW |