| 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 |