Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: Source/bindings/scripts/compute_interfaces_info.py

Issue 173503009: Split generate_global_constructors.py from compute_interfaces_info.py (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: [NoHeader] Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright (C) 2013 Google Inc. All rights reserved. 3 # Copyright (C) 2013 Google Inc. All rights reserved.
4 # 4 #
5 # Redistribution and use in source and binary forms, with or without 5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are 6 # modification, are permitted provided that the following conditions are
7 # met: 7 # met:
8 # 8 #
9 # * Redistributions of source code must retain the above copyright 9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer. 10 # notice, this list of conditions and the following disclaimer.
(...skipping 12 matching lines...) Expand all
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (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
29 # 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.
30 30
31 import optparse 31 import optparse
32 import os 32 import os
33 import cPickle as pickle
34 import posixpath 33 import posixpath
35 import re 34
36 import string 35 from utilities import get_file_contents, write_file, write_pickle_file, get_inte rface_extended_attributes_from_idl, is_callback_interface_from_idl, get_partial_ interface_name_from_idl, get_implemented_interfaces_from_idl, get_parent_interfa ce, get_put_forward_interfaces_from_idl
37 36
38 module_path = os.path.dirname(__file__) 37 module_path = os.path.dirname(__file__)
39 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir)) 38 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
40 39
41 INHERITED_EXTENDED_ATTRIBUTES = set([ 40 INHERITED_EXTENDED_ATTRIBUTES = set([
42 'ActiveDOMObject', 41 'ActiveDOMObject',
43 'DependentLifetime', 42 'DependentLifetime',
44 'WillBeGarbageCollected', 43 'WillBeGarbageCollected',
45 ]) 44 ])
46 45
47 46
48 # interfaces_info is *exported* (in a pickle), and should only contain data 47 # interfaces_info is *exported* (in a pickle), and should only contain data
49 # about an interface that contains paths or is needed by *other* interfaces, 48 # about an interface that contains paths or is needed by *other* interfaces,
50 # i.e., file layout data (to abstract the compiler from file paths) or 49 # i.e., file layout data (to abstract the compiler from file paths) or
51 # public data (to avoid having to read other interfaces unnecessarily). 50 # public data (to avoid having to read other interfaces unnecessarily).
52 # It should *not* contain full information about an interface (e.g., all 51 # It should *not* contain full information about an interface (e.g., all
53 # extended attributes), as this would cause unnecessary rebuilds. 52 # extended attributes), as this would cause unnecessary rebuilds.
54 interfaces_info = {} 53 interfaces_info = {}
55 54
56 # Auxiliary variables (not visible to future build steps) 55 # Auxiliary variables (not visible to future build steps)
57 partial_interface_files = {} 56 partial_interface_files = {}
58 parent_interfaces = {} 57 parent_interfaces = {}
59 extended_attributes_by_interface = {} # interface name -> extended attributes 58 extended_attributes_by_interface = {} # interface name -> extended attributes
60 59
61 60
62 class IdlBadFilenameError(Exception):
63 """Raised if an IDL filename disagrees with the interface name in the file." ""
64 pass
65
66
67 class IdlInterfaceFileNotFoundError(Exception): 61 class IdlInterfaceFileNotFoundError(Exception):
68 """Raised if the IDL file implementing an interface cannot be found.""" 62 """Raised if the IDL file implementing an interface cannot be found."""
69 pass 63 pass
70 64
71 65
72 def parse_options(): 66 def parse_options():
73 usage = 'Usage: %prog [options] [generated1.idl]...' 67 usage = 'Usage: %prog [options] [generated1.idl]...'
74 parser = optparse.OptionParser(usage=usage) 68 parser = optparse.OptionParser(usage=usage)
75 parser.add_option('--event-names-file', help='output file') 69 parser.add_option('--event-names-file', help='output file')
76 parser.add_option('--idl-files-list', help='file listing IDL files') 70 parser.add_option('--idl-files-list', help='file listing IDL files')
77 parser.add_option('--interface-dependencies-file', help='output file') 71 parser.add_option('--interface-dependencies-file', help='output file')
78 parser.add_option('--interfaces-info-file', help='output pickle file') 72 parser.add_option('--interfaces-info-file', help='output pickle file')
79 parser.add_option('--window-constructors-file', help='output file')
80 parser.add_option('--workerglobalscope-constructors-file', help='output file ')
81 parser.add_option('--sharedworkerglobalscope-constructors-file', help='outpu t file')
82 parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='ou tput file')
83 parser.add_option('--serviceworkerglobalscope-constructors-file', help='outp ut file')
84 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') 73 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')
85 options, args = parser.parse_args() 74 options, args = parser.parse_args()
86 if options.event_names_file is None: 75 if options.event_names_file is None:
87 parser.error('Must specify an output file using --event-names-file.') 76 parser.error('Must specify an output file using --event-names-file.')
88 if options.interface_dependencies_file is None: 77 if options.interface_dependencies_file is None:
89 parser.error('Must specify an output file using --interface-dependencies -file.') 78 parser.error('Must specify an output file using --interface-dependencies -file.')
90 if options.interfaces_info_file is None: 79 if options.interfaces_info_file is None:
91 parser.error('Must specify an output file using --interfaces-info-file.' ) 80 parser.error('Must specify an output file using --interfaces-info-file.' )
92 if options.window_constructors_file is None:
93 parser.error('Must specify an output file using --window-constructors-fi le.')
94 if options.workerglobalscope_constructors_file is None:
95 parser.error('Must specify an output file using --workerglobalscope-cons tructors-file.')
96 if options.sharedworkerglobalscope_constructors_file is None:
97 parser.error('Must specify an output file using --sharedworkerglobalscop e-constructors-file.')
98 if options.dedicatedworkerglobalscope_constructors_file is None:
99 parser.error('Must specify an output file using --dedicatedworkerglobals cope-constructors-file.')
100 if options.serviceworkerglobalscope_constructors_file is None:
101 parser.error('Must specify an output file using --serviceworkerglobalsco pe-constructors-file.')
102 if options.idl_files_list is None: 81 if options.idl_files_list is None:
103 parser.error('Must specify a file listing IDL files using --idl-files-li st.') 82 parser.error('Must specify a file listing IDL files using --idl-files-li st.')
104 if options.write_file_only_if_changed is None: 83 if options.write_file_only_if_changed is None:
105 parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.') 84 parser.error('Must specify whether file is only written if changed using --write-file-only-if-changed.')
106 options.write_file_only_if_changed = bool(options.write_file_only_if_changed ) 85 options.write_file_only_if_changed = bool(options.write_file_only_if_changed )
107 return options, args 86 return options, args
108 87
109 88
110 ################################################################################ 89 ################################################################################
111 # Basic file reading/writing
112 ################################################################################
113
114 def get_file_contents(idl_filename):
115 with open(idl_filename) as idl_file:
116 lines = idl_file.readlines()
117 return ''.join(lines)
118
119
120 def write_file(new_lines, destination_filename, only_if_changed):
121 if only_if_changed and os.path.isfile(destination_filename):
122 with open(destination_filename) as destination_file:
123 if destination_file.readlines() == new_lines:
124 return
125 with open(destination_filename, 'w') as destination_file:
126 destination_file.write(''.join(new_lines))
127
128
129 def write_pickle_file(pickle_filename, data, only_if_changed):
130 if only_if_changed and os.path.isfile(pickle_filename):
131 with open(pickle_filename) as pickle_file:
132 if pickle.load(pickle_file) == data:
133 return
134 with open(pickle_filename, 'w') as pickle_file:
135 pickle.dump(data, pickle_file)
136
137
138 ################################################################################
139 # IDL parsing
140 #
141 # We use regular expressions for parsing; this is incorrect (Web IDL is not a
142 # regular language), but simple and sufficient in practice.
143 # Leading and trailing context (e.g. following '{') used to avoid false matches.
144 ################################################################################
145
146 def get_partial_interface_name_from_idl(file_contents):
147 match = re.search(r'partial\s+interface\s+(\w+)\s*{', file_contents)
148 return match and match.group(1)
149
150
151 # identifier-A implements identifier-B;
152 # http://www.w3.org/TR/WebIDL/#idl-implements-statements
153 def get_implemented_interfaces_from_idl(file_contents, interface_name):
154 def get_implemented(left_identifier, right_identifier):
155 # identifier-A must be the current interface
156 if left_identifier != interface_name:
157 raise IdlBadFilenameError("Identifier on the left of the 'implements ' statement should be %s in %s.idl, but found %s" % (interface_name, interface_n ame, left_identifier))
158 return right_identifier
159
160 implements_re = (r'^\s*'
161 r'(\w+)\s+'
162 r'implements\s+'
163 r'(\w+)\s*'
164 r';')
165 implements_matches = re.finditer(implements_re, file_contents, re.MULTILINE)
166 implements_pairs = [(match.group(1), match.group(2))
167 for match in implements_matches]
168 return [get_implemented(left, right) for left, right in implements_pairs]
169
170
171 def is_callback_interface_from_idl(file_contents):
172 match = re.search(r'callback\s+interface\s+\w+\s*{', file_contents)
173 return bool(match)
174
175
176 def get_parent_interface(file_contents):
177 match = re.search(r'interface\s+'
178 r'\w+\s*'
179 r':\s*(\w+)\s*'
180 r'{',
181 file_contents)
182 return match and match.group(1)
183
184
185 def get_interface_extended_attributes_from_idl(file_contents):
186 match = re.search(r'\[(.*)\]\s*'
187 r'((callback|partial)\s+)?'
188 r'(interface|exception)\s+'
189 r'\w+\s*'
190 r'(:\s*\w+\s*)?'
191 r'{',
192 file_contents, flags=re.DOTALL)
193 if not match:
194 return {}
195 # Strip comments
196 # re.compile needed b/c Python 2.6 doesn't support flags in re.sub
197 single_line_comment_re = re.compile(r'//.*$', flags=re.MULTILINE)
198 block_comment_re = re.compile(r'/\*.*?\*/', flags=re.MULTILINE | re.DOTALL)
199 extended_attributes_string = re.sub(single_line_comment_re, '', match.group( 1))
200 extended_attributes_string = re.sub(block_comment_re, '', extended_attribute s_string)
201 extended_attributes = {}
202 # FIXME: this splitting is WRONG: it fails on ExtendedAttributeArgList like
203 # 'NamedConstructor=Foo(a, b)'
204 parts = [extended_attribute.strip()
205 for extended_attribute in extended_attributes_string.split(',')
206 # Discard empty parts, which may exist due to trailing comma
207 if extended_attribute.strip()]
208 for part in parts:
209 name, _, value = map(string.strip, part.partition('='))
210 extended_attributes[name] = value
211 return extended_attributes
212
213
214 def get_put_forward_interfaces_from_idl(file_contents):
215 put_forwards_pattern = (r'\[[^\]]*PutForwards=[^\]]*\]\s+'
216 r'readonly\s+'
217 r'attribute\s+'
218 r'(\w+)')
219 return sorted(set(match.group(1)
220 for match in re.finditer(put_forwards_pattern,
221 file_contents,
222 flags=re.DOTALL)))
223
224
225 ################################################################################
226 # Write files 90 # Write files
227 ################################################################################ 91 ################################################################################
228 92
229 def write_dependencies_file(dependencies_filename, only_if_changed): 93 def write_dependencies_file(dependencies_filename, only_if_changed):
230 """Write the interface dependencies file. 94 """Write the interface dependencies file.
231 95
232 The format is as follows: 96 The format is as follows:
233 97
234 Document.idl P.idl 98 Document.idl P.idl
235 Event.idl 99 Event.idl
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_ dir)) 145 refined_filename, _ = os.path.splitext(os.path.relpath(filename, source_ dir))
282 refined_filename = refined_filename.replace(os.sep, posixpath.sep) 146 refined_filename = refined_filename.replace(os.sep, posixpath.sep)
283 extended_attributes_list = [ 147 extended_attributes_list = [
284 extended_attribute_string(name) 148 extended_attribute_string(name)
285 for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled' 149 for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled'
286 if name in extended_attributes] 150 if name in extended_attributes]
287 lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attribute s_list))) 151 lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attribute s_list)))
288 write_file(lines, destination_filename, only_if_changed) 152 write_file(lines, destination_filename, only_if_changed)
289 153
290 154
291 def write_global_constructors_partial_interface(interface_name, destination_file name, constructor_attributes_list, only_if_changed):
292 lines = (['partial interface %s {\n' % interface_name] +
293 [' %s;\n' % constructor_attribute
294 for constructor_attribute in sorted(constructor_attributes_list)] +
295 ['};\n'])
296 write_file(lines, destination_filename, only_if_changed)
297
298
299 ################################################################################ 155 ################################################################################
300 # Dependency resolution 156 # Dependency resolution
301 ################################################################################ 157 ################################################################################
302 158
303 def include_path(idl_filename, implemented_as=None): 159 def include_path(idl_filename, implemented_as=None):
304 """Returns relative path to header file in POSIX format; used in includes. 160 """Returns relative path to header file in POSIX format; used in includes.
305 161
306 POSIX format is used for consistency of output, so reference tests are 162 POSIX format is used for consistency of output, so reference tests are
307 platform-independent. 163 platform-independent.
308 """ 164 """
(...skipping 24 matching lines...) Expand all
333 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents) 189 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
334 implemented_as = extended_attributes.get('ImplementedAs') 190 implemented_as = extended_attributes.get('ImplementedAs')
335 # FIXME: remove [NoHeader] once switch to Python 191 # FIXME: remove [NoHeader] once switch to Python
336 this_include_path = (include_path(idl_filename, implemented_as) 192 this_include_path = (include_path(idl_filename, implemented_as)
337 if 'NoHeader' not in extended_attributes else None) 193 if 'NoHeader' not in extended_attributes else None)
338 194
339 # Handle partial interfaces 195 # Handle partial interfaces
340 partial_interface_name = get_partial_interface_name_from_idl(idl_file_conten ts) 196 partial_interface_name = get_partial_interface_name_from_idl(idl_file_conten ts)
341 if partial_interface_name: 197 if partial_interface_name:
342 add_paths_to_partials_dict(partial_interface_name, full_path, this_inclu de_path) 198 add_paths_to_partials_dict(partial_interface_name, full_path, this_inclu de_path)
343 return False 199 return
344 200
345 # If not a partial interface, the basename is the interface name 201 # If not a partial interface, the basename is the interface name
346 interface_name, _ = os.path.splitext(os.path.basename(idl_filename)) 202 interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
347 203
348 interfaces_info[interface_name] = { 204 interfaces_info[interface_name] = {
349 'full_path': full_path, 205 'full_path': full_path,
350 'implements_interfaces': get_implemented_interfaces_from_idl(idl_file_co ntents, interface_name), 206 'implements_interfaces': get_implemented_interfaces_from_idl(idl_file_co ntents, interface_name),
351 'is_callback_interface': is_callback_interface_from_idl(idl_file_content s), 207 'is_callback_interface': is_callback_interface_from_idl(idl_file_content s),
352 # Interfaces that are referenced (used as types) and that we introspect 208 # Interfaces that are referenced (used as types) and that we introspect
353 # during code generation (beyond interface-level data ([ImplementedAs], 209 # during code generation (beyond interface-level data ([ImplementedAs],
354 # is_callback_interface, ancestors, and inherited extended attributes): 210 # is_callback_interface, ancestors, and inherited extended attributes):
355 # deep dependencies. 211 # deep dependencies.
356 # These cause rebuilds of referrers, due to the dependency, so these 212 # These cause rebuilds of referrers, due to the dependency, so these
357 # should be minimized; currently only targets of [PutForwards]. 213 # should be minimized; currently only targets of [PutForwards].
358 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co ntents), 214 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co ntents),
359 } 215 }
360 if this_include_path: 216 if this_include_path:
361 interfaces_info[interface_name]['include_path'] = this_include_path 217 interfaces_info[interface_name]['include_path'] = this_include_path
362 if implemented_as: 218 if implemented_as:
363 interfaces_info[interface_name]['implemented_as'] = implemented_as 219 interfaces_info[interface_name]['implemented_as'] = implemented_as
364 220
365 return True
366
367
368 def generate_constructor_attribute_list(interface_name, extended_attributes):
369 extended_attributes_list = [
370 name + '=' + extended_attributes[name]
371 for name in 'Conditional', 'PerContextEnabled', 'RuntimeEnabled'
372 if name in extended_attributes]
373 if extended_attributes_list:
374 extended_string = '[%s] ' % ', '.join(extended_attributes_list)
375 else:
376 extended_string = ''
377
378 attribute_string = 'attribute {interface_name}Constructor {interface_name}'. format(interface_name=interface_name)
379 attributes_list = [extended_string + attribute_string]
380
381 # In addition to the regular property, for every [NamedConstructor]
382 # extended attribute on an interface, a corresponding property MUST exist
383 # on the ECMAScript global object.
384 if 'NamedConstructor' in extended_attributes:
385 named_constructor = extended_attributes['NamedConstructor']
386 # Extract function name, namely everything before opening '('
387 constructor_name = re.sub(r'\(.*', '', named_constructor)
388 # Note the reduplicated 'ConstructorConstructor'
389 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name)
390 attributes_list.append(extended_string + attribute_string)
391
392 return attributes_list
393
394
395 def record_global_constructors_and_extended_attributes(idl_filename, global_cons tructors):
396 interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
397 full_path = os.path.realpath(idl_filename)
398 idl_file_contents = get_file_contents(full_path)
399 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
400
401 # Record extended attributes 221 # Record extended attributes
402 extended_attributes_by_interface[interface_name] = extended_attributes 222 extended_attributes_by_interface[interface_name] = extended_attributes
403 223
404 # Record global constructors
405 if (not is_callback_interface_from_idl(idl_file_contents) and
406 'NoInterfaceObject' not in extended_attributes):
407 global_contexts = extended_attributes.get('GlobalContext', 'Window').spl it('&')
408 new_constructor_list = generate_constructor_attribute_list(interface_nam e, extended_attributes)
409 for global_object in global_contexts:
410 global_constructors[global_object].extend(new_constructor_list)
411
412 # Record parents 224 # Record parents
413 parent = get_parent_interface(idl_file_contents) 225 parent = get_parent_interface(idl_file_contents)
414 if parent: 226 if parent:
415 parent_interfaces[interface_name] = parent 227 parent_interfaces[interface_name] = parent
416 228
417 229
418 def record_extended_attributes(idl_filename):
419 interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
420 full_path = os.path.realpath(idl_filename)
421 idl_file_contents = get_file_contents(full_path)
422 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
423 extended_attributes_by_interface[interface_name] = extended_attributes
424
425
426 def generate_ancestors_and_inherited_extended_attributes(interface_name): 230 def generate_ancestors_and_inherited_extended_attributes(interface_name):
427 interface_info = interfaces_info[interface_name] 231 interface_info = interfaces_info[interface_name]
428 interface_extended_attributes = extended_attributes_by_interface[interface_n ame] 232 interface_extended_attributes = extended_attributes_by_interface[interface_n ame]
429 inherited_extended_attributes = dict( 233 inherited_extended_attributes = dict(
430 (key, value) 234 (key, value)
431 for key, value in interface_extended_attributes.iteritems() 235 for key, value in interface_extended_attributes.iteritems()
432 if key in INHERITED_EXTENDED_ATTRIBUTES) 236 if key in INHERITED_EXTENDED_ATTRIBUTES)
433 237
434 def generate_ancestors(interface_name): 238 def generate_ancestors(interface_name):
435 while interface_name in parent_interfaces: 239 while interface_name in parent_interfaces:
(...skipping 13 matching lines...) Expand all
449 # IDL files, or generated support files. 253 # IDL files, or generated support files.
450 ancestor_extended_attributes = extended_attributes_by_interface.get(ance stor, {}) 254 ancestor_extended_attributes = extended_attributes_by_interface.get(ance stor, {})
451 inherited_extended_attributes.update(dict( 255 inherited_extended_attributes.update(dict(
452 (key, value) 256 (key, value)
453 for key, value in ancestor_extended_attributes.iteritems() 257 for key, value in ancestor_extended_attributes.iteritems()
454 if key in INHERITED_EXTENDED_ATTRIBUTES)) 258 if key in INHERITED_EXTENDED_ATTRIBUTES))
455 if inherited_extended_attributes: 259 if inherited_extended_attributes:
456 interface_info['inherited_extended_attributes'] = inherited_extended_att ributes 260 interface_info['inherited_extended_attributes'] = inherited_extended_att ributes
457 261
458 262
459 def parse_idl_files(idl_files, global_constructors_filenames): 263 def parse_idl_files(idl_files):
460 """Compute dependencies between IDL files, and return constructors on global objects. 264 """Compute information about IDL files.
461 265
462 Primary effect is computing info about main interfaces, stored in global 266 Primary effect is computing info about main interfaces, stored in global
463 interfaces_info. 267 interfaces_info.
464 The keys are the interfaces for which bindings are generated;
465 this does not include interfaces implemented by another interface.
466
467 Returns:
468 global_constructors:
469 dict of global objects -> list of constructors on that object
470 """ 268 """
471 global_constructors = dict([ 269 # Generate dependencies.
472 (global_object, [])
473 for global_object in global_constructors_filenames])
474
475 # Generate dependencies, and (for main IDL files), record
476 # global_constructors and extended_attributes_by_interface.
477 for idl_filename in idl_files: 270 for idl_filename in idl_files:
478 # Test skips partial interfaces 271 generate_dependencies(idl_filename)
479 if generate_dependencies(idl_filename):
480 record_global_constructors_and_extended_attributes(idl_filename, glo bal_constructors)
481 272
482 for interface_name in interfaces_info: 273 for interface_name in interfaces_info:
483 generate_ancestors_and_inherited_extended_attributes(interface_name) 274 generate_ancestors_and_inherited_extended_attributes(interface_name)
484 275
485 # Add constructors on global objects to partial interfaces
486 # These are all partial interfaces, but the files are dynamically generated,
487 # so they need to be handled separately from static partial interfaces.
488 for global_object, constructor_filename in global_constructors_filenames.ite ritems():
489 if global_object in interfaces_info:
490 # No include path needed, as already included in the header file
491 add_paths_to_partials_dict(global_object, constructor_filename)
492
493 # An IDL file's dependencies are partial interface files that extend it, 276 # An IDL file's dependencies are partial interface files that extend it,
494 # and files for other interfaces that this interfaces implements. 277 # and files for other interfaces that this interfaces implements.
495 for interface_name, interface_info in interfaces_info.iteritems(): 278 for interface_name, interface_info in interfaces_info.iteritems():
496 partial_interfaces_full_paths, partial_interfaces_include_paths = ( 279 partial_interfaces_full_paths, partial_interfaces_include_paths = (
497 (partial_interface_files[interface_name]['full_paths'], 280 (partial_interface_files[interface_name]['full_paths'],
498 partial_interface_files[interface_name]['include_paths']) 281 partial_interface_files[interface_name]['include_paths'])
499 if interface_name in partial_interface_files else ([], [])) 282 if interface_name in partial_interface_files else ([], []))
500 283
501 implemented_interfaces = interface_info['implements_interfaces'] 284 implemented_interfaces = interface_info['implements_interfaces']
502 try: 285 try:
503 implemented_interfaces_full_paths = [ 286 implemented_interfaces_full_paths = [
504 interfaces_info[interface]['full_path'] 287 interfaces_info[interface]['full_path']
505 for interface in implemented_interfaces] 288 for interface in implemented_interfaces]
506 implemented_interfaces_include_paths = [ 289 implemented_interfaces_include_paths = [
507 interfaces_info[interface]['include_path'] 290 interfaces_info[interface]['include_path']
508 for interface in implemented_interfaces 291 for interface in implemented_interfaces
509 if 'include_path' in interfaces_info[interface]] 292 if 'include_path' in interfaces_info[interface]]
510 except KeyError as key_name: 293 except KeyError as key_name:
511 raise IdlInterfaceFileNotFoundError('Could not find the IDL file whe re the following implemented interface is defined: %s' % key_name) 294 raise IdlInterfaceFileNotFoundError('Could not find the IDL file whe re the following implemented interface is defined: %s' % key_name)
512 295
513 interface_info['dependencies_full_paths'] = ( 296 interface_info['dependencies_full_paths'] = (
514 partial_interfaces_full_paths + 297 partial_interfaces_full_paths +
515 implemented_interfaces_full_paths) 298 implemented_interfaces_full_paths)
516 interface_info['dependencies_include_paths'] = ( 299 interface_info['dependencies_include_paths'] = (
517 partial_interfaces_include_paths + 300 partial_interfaces_include_paths +
518 implemented_interfaces_include_paths) 301 implemented_interfaces_include_paths)
519 302
520 return global_constructors
521
522 303
523 ################################################################################ 304 ################################################################################
524 305
525 def main(): 306 def main():
526 options, args = parse_options() 307 options, args = parse_options()
527 308
528 # Static IDL files are passed in a file (generated at GYP time), due to OS 309 # Static IDL files are passed in a file (generated at GYP time), due to OS
529 # command line length limits 310 # command line length limits
530 with open(options.idl_files_list) as idl_files_list: 311 with open(options.idl_files_list) as idl_files_list:
531 idl_files = [line.rstrip('\n') for line in idl_files_list] 312 idl_files = [line.rstrip('\n') for line in idl_files_list]
532 # Generated IDL files are passed at the command line, since these are in the 313 # Generated IDL files are passed at the command line, since these are in the
533 # build directory, which is determined at build time, not GYP time, so these 314 # build directory, which is determined at build time, not GYP time, so these
534 # cannot be included in the file listing static files 315 # cannot be included in the file listing static files
535 idl_files.extend(args) 316 idl_files.extend(args)
536 317
537 only_if_changed = options.write_file_only_if_changed 318 only_if_changed = options.write_file_only_if_changed
538 global_constructors_filenames = {
539 'Window': options.window_constructors_file,
540 'WorkerGlobalScope': options.workerglobalscope_constructors_file,
541 'SharedWorkerGlobalScope': options.sharedworkerglobalscope_constructors_ file,
542 'DedicatedWorkerGlobalScope': options.dedicatedworkerglobalscope_constru ctors_file,
543 'ServiceWorkerGlobalScope': options.serviceworkerglobalscope_constructor s_file,
544 }
545 319
546 global_constructors = parse_idl_files(idl_files, global_constructors_filenam es) 320 parse_idl_files(idl_files)
547 321 write_pickle_file(options.interfaces_info_file, interfaces_info, only_if_cha nged)
548 write_dependencies_file(options.interface_dependencies_file, only_if_changed ) 322 write_dependencies_file(options.interface_dependencies_file, only_if_changed )
549 write_pickle_file(options.interfaces_info_file, interfaces_info, only_if_cha nged)
550 for interface_name, filename in global_constructors_filenames.iteritems():
551 if interface_name in interfaces_info:
552 write_global_constructors_partial_interface(interface_name, filename , global_constructors[interface_name], only_if_changed)
553 write_event_names_file(options.event_names_file, only_if_changed) 323 write_event_names_file(options.event_names_file, only_if_changed)
554 324
555 325
556 if __name__ == '__main__': 326 if __name__ == '__main__':
557 main() 327 main()
OLDNEW
« no previous file with comments | « Source/bindings/generated_bindings.gyp ('k') | Source/bindings/scripts/generate_global_constructors.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698