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

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

Issue 173803006: Split generate_global_constructors.py out of compute_dependencies.py (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Cleaner Created 6 years, 10 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
26
27 global_objects = {}
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
35 options, args = parser.parse_args()
36
37 if options.idl_files_list is None:
38 parser.error('Must specify a file listing IDL files using --idl-files-li st.')
39 if options.write_file_only_if_changed is None:
40 parser.error('Must specify whether output files are only written if chan ged using --write-file-only-if-changed.')
41 options.write_file_only_if_changed = bool(options.write_file_only_if_changed )
42
43 return options, args
44
45
46 def record_global_constructors(idl_filename):
47 interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
48 full_path = os.path.realpath(idl_filename)
49 idl_file_contents = get_file_contents(full_path)
50 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
51
52 # An interface property is produced for every non-callback interface
53 # that does not have [NoInterfaceObject].
54 # Callback interfaces with constants also have interface properties,
55 # but there are none of these in Blink.
56 # http://heycam.github.io/webidl/#es-interfaces
57 if (is_callback_interface_from_idl(idl_file_contents) or
58 'NoInterfaceObject' in extended_attributes):
59 return
60
61 global_contexts = extended_attributes.get('GlobalContext', 'Window').split(' &')
62 new_constructors_list = generate_global_constructors_list(interface_name, ex tended_attributes)
63 for interface_name in global_contexts:
64 global_objects[interface_name]['constructors'].extend(new_constructors_l ist)
65
66
67 def generate_global_constructors_list(interface_name, extended_attributes):
68 extended_attributes_list = [
69 name + '=' + extended_attributes[name]
70 for name in 'Conditional', 'PerContextEnabled', 'RuntimeEnabled'
71 if name in extended_attributes]
72 if extended_attributes_list:
73 extended_string = '[%s] ' % ', '.join(extended_attributes_list)
74 else:
75 extended_string = ''
76
77 attribute_string = 'attribute {interface_name}Constructor {interface_name}'. format(interface_name=interface_name)
78 attributes_list = [extended_string + attribute_string]
79
80 # In addition to the usual interface property, for every [NamedConstructor]
81 # extended attribute on an interface, a corresponding property MUST exist
82 # on the ECMAScript global object.
83 # http://heycam.github.io/webidl/#NamedConstructor
84 if 'NamedConstructor' in extended_attributes:
85 named_constructor = extended_attributes['NamedConstructor']
86 # Extract function name, namely everything before opening '('
87 constructor_name = re.sub(r'\(.*', '', named_constructor)
88 # Note the reduplicated 'ConstructorConstructor'
89 # FIXME: rename to NamedConsructor
90 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name)
91 attributes_list.append(extended_string + attribute_string)
92
93 return attributes_list
94
95
96 def write_global_constructors_partial_interface(interface_name, destination_file name, constructor_attributes_list, only_if_changed):
97 lines = (['partial interface %s {\n' % interface_name] +
98 [' %s;\n' % constructor_attribute
99 for constructor_attribute in sorted(constructor_attributes_list)] +
100 ['};\n'])
101 write_file(lines, destination_filename, only_if_changed)
102
103
104 ################################################################################
105
106 def main():
107 options, args = parse_options()
108
109 # Input IDL files are passed in a file, due to OS command line length
110 # limits. This is generated at GYP time, which is ok b/c files are static.
111 with open(options.idl_files_list) as idl_files_list:
112 idl_files = [line.rstrip('\n') for line in idl_files_list]
113
114 # Output IDL files (to generate) are passed at the command line, since
115 # these are in the build directory, which is determined at build time, not
116 # GYP time.
117 # These are passed as pairs of GlobalObjectName, GlobalObject.idl
118 interface_name_filename = [(args[i], args[i + 1])
119 for i in range(0, len(args), 2)]
120 global_objects.update(
121 (interface_name, {
122 'filename': filename,
123 'constructors': [],
124 })
125 for interface_name, filename in interface_name_filename)
126
127 for idl_filename in idl_files:
128 record_global_constructors(idl_filename)
129
130 for interface_name, global_object in global_objects.iteritems():
131 write_global_constructors_partial_interface(interface_name, global_objec t['filename'], global_object['constructors'], options.write_file_only_if_changed )
132
133
134 if __name__ == '__main__':
135 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