OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Generates interface properties on global objects. | 7 """Generates interface properties on global objects. |
8 | 8 |
9 Concretely these are implemented as "constructor attributes", meaning | 9 Concretely these are implemented as "constructor attributes", meaning |
10 "attributes whose name ends with Constructor" (special-cased by code generator), | 10 "attributes whose name ends with Constructor" (special-cased by code generator), |
11 hence "global constructors" for short. | 11 hence "global constructors" for short. |
12 | 12 |
13 For reference on global objects, see: | 13 For reference on global objects, see: |
14 http://www.chromium.org/blink/webidl/blink-idl-extended-attributes#TOC-GlobalCon
text-i- | 14 http://www.chromium.org/blink/webidl/blink-idl-extended-attributes#TOC-GlobalCon
text-i- |
15 | 15 |
16 Design document: http://www.chromium.org/developers/design-documents/idl-build | 16 Design document: http://www.chromium.org/developers/design-documents/idl-build |
17 """ | 17 """ |
18 | 18 |
19 import optparse | 19 import optparse |
20 import os | 20 import os |
21 import re | 21 import re |
22 import sys | 22 import sys |
23 | 23 |
24 from utilities import get_file_contents, write_file, get_interface_extended_attr
ibutes_from_idl, is_callback_interface_from_idl | 24 from utilities import get_file_contents, write_file, get_interface_extended_attr
ibutes_from_idl, is_callback_interface_from_idl |
25 | 25 |
26 global_objects = {} | 26 global_objects = {} |
27 | 27 |
28 | 28 |
| 29 HEADER_FORMAT = """ |
| 30 // Stub header file for {{idl_basename}} |
| 31 // Required because the IDL compiler assumes that a corresponding header file |
| 32 // exists for each IDL file. |
| 33 """ |
| 34 |
29 def parse_options(): | 35 def parse_options(): |
30 parser = optparse.OptionParser() | 36 parser = optparse.OptionParser() |
31 parser.add_option('--idl-files-list', help='file listing IDL files') | 37 parser.add_option('--idl-files-list', help='file listing IDL files') |
32 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') | 38 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') |
33 | 39 |
34 options, args = parser.parse_args() | 40 options, args = parser.parse_args() |
35 | 41 |
36 if options.idl_files_list is None: | 42 if options.idl_files_list is None: |
37 parser.error('Must specify a file listing IDL files using --idl-files-li
st.') | 43 parser.error('Must specify a file listing IDL files using --idl-files-li
st.') |
38 if options.write_file_only_if_changed is None: | 44 if options.write_file_only_if_changed is None: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 # Extract function name, namely everything before opening '(' | 91 # Extract function name, namely everything before opening '(' |
86 constructor_name = re.sub(r'\(.*', '', named_constructor) | 92 constructor_name = re.sub(r'\(.*', '', named_constructor) |
87 # Note the reduplicated 'ConstructorConstructor' | 93 # Note the reduplicated 'ConstructorConstructor' |
88 # FIXME: rename to NamedConstructor | 94 # FIXME: rename to NamedConstructor |
89 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_
name, constructor_name) | 95 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_
name, constructor_name) |
90 attributes_list.append(extended_string + attribute_string) | 96 attributes_list.append(extended_string + attribute_string) |
91 | 97 |
92 return attributes_list | 98 return attributes_list |
93 | 99 |
94 | 100 |
95 def write_global_constructors_partial_interface(interface_name, destination_file
name, constructor_attributes_list, only_if_changed): | 101 def write_global_constructors_partial_interface(interface_name, idl_filename, co
nstructor_attributes_list, only_if_changed): |
96 # FIXME: replace this with a simple Jinja template | 102 # FIXME: replace this with a simple Jinja template |
97 lines = (['[\n'] + | 103 lines = (['partial interface %s {\n' % interface_name] + |
98 [' NoHeader,\n'] + | |
99 [']\n'] + | |
100 ['partial interface %s {\n' % interface_name] + | |
101 [' %s;\n' % constructor_attribute | 104 [' %s;\n' % constructor_attribute |
102 # FIXME: sort by interface name (not first by extended attributes) | 105 # FIXME: sort by interface name (not first by extended attributes) |
103 for constructor_attribute in sorted(constructor_attributes_list)]
+ | 106 for constructor_attribute in sorted(constructor_attributes_list)]
+ |
104 ['};\n']) | 107 ['};\n']) |
105 write_file(''.join(lines), destination_filename, only_if_changed) | 108 write_file(''.join(lines), idl_filename, only_if_changed) |
| 109 header_filename = os.path.splitext(idl_filename)[0] + '.h' |
| 110 idl_basename = os.path.basename(idl_filename) |
| 111 write_file(HEADER_FORMAT.format(idl_basename=idl_basename), |
| 112 header_filename, only_if_changed) |
106 | 113 |
107 | 114 |
108 ################################################################################ | 115 ################################################################################ |
109 | 116 |
110 def main(): | 117 def main(): |
111 options, args = parse_options() | 118 options, args = parse_options() |
112 | 119 |
113 # Input IDL files are passed in a file, due to OS command line length | 120 # Input IDL files are passed in a file, due to OS command line length |
114 # limits. This is generated at GYP time, which is ok b/c files are static. | 121 # limits. This is generated at GYP time, which is ok b/c files are static. |
115 with open(options.idl_files_list) as idl_files_list: | 122 with open(options.idl_files_list) as idl_files_list: |
116 idl_files = [line.rstrip('\n') for line in idl_files_list] | 123 idl_files = [line.rstrip('\n') for line in idl_files_list] |
117 | 124 |
118 # Output IDL files (to generate) are passed at the command line, since | 125 # Output IDL files (to generate) are passed at the command line, since |
119 # these are in the build directory, which is determined at build time, not | 126 # these are in the build directory, which is determined at build time, not |
120 # GYP time. | 127 # GYP time. |
121 # These are passed as pairs of GlobalObjectName, GlobalObject.idl | 128 # These are passed as pairs of GlobalObjectName, GlobalObject.idl |
122 interface_name_filename = [(args[i], args[i + 1]) | 129 interface_name_idl_filename = [(args[i], args[i + 1]) |
123 for i in range(0, len(args), 2)] | 130 for i in range(0, len(args), 2)] |
124 global_objects.update( | 131 global_objects.update( |
125 (interface_name, { | 132 (interface_name, { |
126 'filename': filename, | 133 'idl_filename': idl_filename, |
127 'constructors': [], | 134 'constructors': [], |
128 }) | 135 }) |
129 for interface_name, filename in interface_name_filename) | 136 for interface_name, idl_filename in interface_name_idl_filename) |
130 | 137 |
131 for idl_filename in idl_files: | 138 for idl_filename in idl_files: |
132 record_global_constructors(idl_filename) | 139 record_global_constructors(idl_filename) |
133 | 140 |
134 for interface_name, global_object in global_objects.iteritems(): | 141 for interface_name, global_object in global_objects.iteritems(): |
135 write_global_constructors_partial_interface(interface_name, global_objec
t['filename'], global_object['constructors'], options.write_file_only_if_changed
) | 142 write_global_constructors_partial_interface( |
| 143 interface_name, |
| 144 global_object['idl_filename'], |
| 145 global_object['constructors'], |
| 146 options.write_file_only_if_changed) |
136 | 147 |
137 | 148 |
138 if __name__ == '__main__': | 149 if __name__ == '__main__': |
139 sys.exit(main()) | 150 sys.exit(main()) |
OLD | NEW |