Chromium Code Reviews| 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 |