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

Side by Side Diff: Source/bindings/scripts/generate_global_constructors.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
(Empty)
1 #!/usr/bin/python
2 #
3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """Generates interface properties on global objects.
8
9 Concretely these are implemented as "constructor attributes", meaning
10 "attributes whose name ends with Constructor" (special-cased by code generator),
11 hence "global constructors" for short.
12
13 For reference on global objects, see:
14 http://www.chromium.org/blink/webidl/blink-idl-extended-attributes#TOC-GlobalCon text-i-
15
16 Design document:
17 http://www.chromium.org/developers/design-documents/idl-build
18 """
19
20 import optparse
21 import os
22 import re
23 import sys
24
25 from utilities import get_file_contents, write_file, get_interface_extended_attr ibutes_from_idl, is_callback_interface_from_idl, get_partial_interface_name_from _idl
26
27 global_constructors = {}
28
29
30 def parse_options():
31 parser = optparse.OptionParser()
32 parser.add_option('--idl-files-list', help='file listing IDL files')
33 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')
34 parser.add_option('--window-constructors-file', help='output file')
35 parser.add_option('--workerglobalscope-constructors-file', help='output file ')
36 parser.add_option('--sharedworkerglobalscope-constructors-file', help='outpu t file')
37 parser.add_option('--dedicatedworkerglobalscope-constructors-file', help='ou tput file')
38 parser.add_option('--serviceworkerglobalscope-constructors-file', help='outp ut file')
39
40 options, _ = parser.parse_args()
41
42 if options.idl_files_list is None:
43 parser.error('Must specify a file listing IDL files using --idl-files-li st.')
44 if options.write_file_only_if_changed is None:
45 parser.error('Must specify whether output files are only written if chan ged using --write-file-only-if-changed.')
46 options.write_file_only_if_changed = bool(options.write_file_only_if_changed )
47 if options.window_constructors_file is None:
48 parser.error('Must specify an output file using --window-constructors-fi le.')
49 if options.workerglobalscope_constructors_file is None:
50 parser.error('Must specify an output file using --workerglobalscope-cons tructors-file.')
51 if options.sharedworkerglobalscope_constructors_file is None:
52 parser.error('Must specify an output file using --sharedworkerglobalscop e-constructors-file.')
53 if options.dedicatedworkerglobalscope_constructors_file is None:
54 parser.error('Must specify an output file using --dedicatedworkerglobals cope-constructors-file.')
55 if options.serviceworkerglobalscope_constructors_file is None:
56 parser.error('Must specify an output file using --serviceworkerglobalsco pe-constructors-file.')
57
58 return options
59
60
61 def record_global_constructors(idl_filename):
62 interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
63 full_path = os.path.realpath(idl_filename)
64 idl_file_contents = get_file_contents(full_path)
65 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
66
67 # An interface property is produced for every non-callback interface
68 # that does not have [NoInterfaceObject].
69 # Callback interfaces with constants also have interface properties,
70 # but there are none of these in Blink.
71 # http://heycam.github.io/webidl/#es-interfaces
72 if (is_callback_interface_from_idl(idl_file_contents) or
73 get_partial_interface_name_from_idl(idl_file_contents) or
74 'NoInterfaceObject' in extended_attributes):
75 return
76
77 global_contexts = extended_attributes.get('GlobalContext', 'Window').split(' &')
78 new_constructors_list = generate_global_constructors_list(interface_name, ex tended_attributes)
79 for interface_name in global_contexts:
80 global_constructors[interface_name].extend(new_constructors_list)
81
82
83 def generate_global_constructors_list(interface_name, extended_attributes):
84 extended_attributes_list = [
85 name + '=' + extended_attributes[name]
86 for name in 'Conditional', 'PerContextEnabled', 'RuntimeEnabled'
87 if name in extended_attributes]
88 if extended_attributes_list:
89 extended_string = '[%s] ' % ', '.join(extended_attributes_list)
90 else:
91 extended_string = ''
92
93 attribute_string = 'attribute {interface_name}Constructor {interface_name}'. format(interface_name=interface_name)
94 attributes_list = [extended_string + attribute_string]
95
96 # In addition to the usual interface property, for every [NamedConstructor]
97 # extended attribute on an interface, a corresponding property MUST exist
98 # on the ECMAScript global object.
99 # http://heycam.github.io/webidl/#NamedConstructor
100 if 'NamedConstructor' in extended_attributes:
101 named_constructor = extended_attributes['NamedConstructor']
102 # Extract function name, namely everything before opening '('
103 constructor_name = re.sub(r'\(.*', '', named_constructor)
104 # Note the reduplicated 'ConstructorConstructor'
105 # FIXME: rename to NamedConstructor
106 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name)
107 attributes_list.append(extended_string + attribute_string)
108
109 return attributes_list
110
111
112 def write_global_constructors_partial_interface(interface_name, destination_file name, constructor_attributes_list, only_if_changed):
113 # FIXME: replace this with a simple Jinja template
114 lines = (['[\n'] +
115 [' NoHeader,\n'] +
116 [']\n'] +
117 ['partial interface %s {\n' % interface_name] +
118 [' %s;\n' % constructor_attribute
119 # FIXME: sort by interface name (not first by extended attributes)
120 for constructor_attribute in sorted(constructor_attributes_list)] +
121 ['};\n'])
122 write_file(lines, destination_filename, only_if_changed)
123
124
125 ################################################################################
126
127 def main():
128 options = parse_options()
129
130 # Input IDL files are passed in a file, due to OS command line length
131 # limits. This is generated at GYP time, which is ok b/c files are static.
132 with open(options.idl_files_list) as idl_files_list:
133 idl_files = [line.rstrip('\n') for line in idl_files_list]
134
135 # Output IDL files (to generate) are passed at the command line, since
136 # these are in the build directory, which is determined at build time, not
137 # GYP time.
138 global_constructors_filenames = {
139 'Window': options.window_constructors_file,
140 'WorkerGlobalScope': options.workerglobalscope_constructors_file,
141 'SharedWorkerGlobalScope': options.sharedworkerglobalscope_constructors_ file,
142 'DedicatedWorkerGlobalScope': options.dedicatedworkerglobalscope_constru ctors_file,
143 'ServiceWorkerGlobalScope': options.serviceworkerglobalscope_constructor s_file,
144 }
145 global_constructors.update(dict([
146 (global_object, [])
147 for global_object in global_constructors_filenames]))
148
149 for idl_filename in idl_files:
150 record_global_constructors(idl_filename)
151
152 for interface_name, filename in global_constructors_filenames.iteritems():
153 write_global_constructors_partial_interface(interface_name, filename, gl obal_constructors[interface_name], options.write_file_only_if_changed)
154
155
156 if __name__ == '__main__':
157 sys.exit(main())
OLDNEW
« no previous file with comments | « Source/bindings/scripts/compute_interfaces_info.py ('k') | Source/bindings/scripts/utilities.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698