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

Side by Side Diff: sky/engine/bindings/scripts/generate_global_constructors.py

Issue 922053002: Remove unused V8 integration code in Sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 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
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://heycam.github.io/webidl/#Global
15 http://heycam.github.io/webidl/#Exposed
16
17 Design document: http://www.chromium.org/developers/design-documents/idl-build
18 """
19
20 import itertools
21 import optparse
22 import os
23 import cPickle as pickle
24 import re
25 import sys
26
27 from collections import defaultdict
28 from utilities import get_file_contents, idl_filename_to_interface_name, read_fi le_to_list, write_file, get_interface_extended_attributes_from_idl, is_callback_ interface_from_idl
29
30 interface_name_to_global_names = {}
31 global_name_to_constructors = defaultdict(list)
32
33
34 HEADER_FORMAT = """// Stub header file for {{idl_basename}}
35 // Required because the IDL compiler assumes that a corresponding header file
36 // exists for each IDL file.
37 """
38
39 def parse_options():
40 parser = optparse.OptionParser()
41 parser.add_option('--idl-files-list', help='file listing IDL files')
42 parser.add_option('--global-objects-file', help='pickle file of global objec ts')
43 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')
44
45 options, args = parser.parse_args()
46
47 if options.idl_files_list is None:
48 parser.error('Must specify a file listing IDL files using --idl-files-li st.')
49 if options.global_objects_file is None:
50 parser.error('Must specify a pickle file of global objects using --globa l-objects-file.')
51 if options.write_file_only_if_changed is None:
52 parser.error('Must specify whether output files are only written if chan ged using --write-file-only-if-changed.')
53 options.write_file_only_if_changed = bool(options.write_file_only_if_changed )
54
55 return options, args
56
57
58 def flatten_list(iterable):
59 return list(itertools.chain.from_iterable(iterable))
60
61
62 def interface_name_to_constructors(interface_name):
63 """Returns constructors for an interface."""
64 global_names = interface_name_to_global_names[interface_name]
65 return flatten_list(global_name_to_constructors[global_name]
66 for global_name in global_names)
67
68
69 def record_global_constructors(idl_filename):
70 interface_name = idl_filename_to_interface_name(idl_filename)
71 full_path = os.path.realpath(idl_filename)
72 idl_file_contents = get_file_contents(full_path)
73 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
74
75 # An interface property is produced for every non-callback interface
76 # that does not have [NoInterfaceObject].
77 # Callback interfaces with constants also have interface properties,
78 # but there are none of these in Blink.
79 # http://heycam.github.io/webidl/#es-interfaces
80 if (is_callback_interface_from_idl(idl_file_contents) or
81 'NoInterfaceObject' in extended_attributes):
82 return
83
84 # The [Exposed] extended attribute MUST take an identifier list. Each
85 # identifier in the list MUST be a global name. An interface or interface
86 # member the extended attribute applies to will be exposed only on objects
87 # associated with ECMAScript global environments whose global object
88 # implements an interface that has a matching global name.
89 exposed_global_names = extended_attributes.get('Exposed', 'Window').strip('( )').split(',')
90 new_constructors_list = generate_global_constructors_list(interface_name, ex tended_attributes)
91 for exposed_global_name in exposed_global_names:
92 global_name_to_constructors[exposed_global_name].extend(new_constructors _list)
93
94
95 def generate_global_constructors_list(interface_name, extended_attributes):
96 extended_attributes_list = [
97 name + '=' + extended_attributes[name]
98 for name in 'Conditional', 'RuntimeEnabled'
99 if name in extended_attributes]
100 if extended_attributes_list:
101 extended_string = '[%s] ' % ', '.join(extended_attributes_list)
102 else:
103 extended_string = ''
104
105 attribute_string = 'attribute {interface_name}Constructor {interface_name}'. format(interface_name=interface_name)
106 attributes_list = [extended_string + attribute_string]
107
108 # In addition to the usual interface property, for every [NamedConstructor]
109 # extended attribute on an interface, a corresponding property MUST exist
110 # on the ECMAScript global object.
111 # http://heycam.github.io/webidl/#NamedConstructor
112 if 'NamedConstructor' in extended_attributes:
113 named_constructor = extended_attributes['NamedConstructor']
114 # Extract function name, namely everything before opening '('
115 constructor_name = re.sub(r'\(.*', '', named_constructor)
116 # Note the reduplicated 'ConstructorConstructor'
117 # FIXME: rename to NamedConstructor
118 attribute_string = 'attribute %sConstructorConstructor %s' % (interface_ name, constructor_name)
119 attributes_list.append(extended_string + attribute_string)
120
121 return attributes_list
122
123
124 def write_global_constructors_partial_interface(interface_name, idl_filename, co nstructor_attributes_list, only_if_changed):
125 # FIXME: replace this with a simple Jinja template
126 lines = (['partial interface %s {\n' % interface_name] +
127 [' %s;\n' % constructor_attribute
128 # FIXME: sort by interface name (not first by extended attributes)
129 for constructor_attribute in sorted(constructor_attributes_list)] +
130 ['};\n'])
131 write_file(''.join(lines), idl_filename, only_if_changed)
132 header_filename = os.path.splitext(idl_filename)[0] + '.h'
133 idl_basename = os.path.basename(idl_filename)
134 write_file(HEADER_FORMAT.format(idl_basename=idl_basename),
135 header_filename, only_if_changed)
136
137
138 ################################################################################
139
140 def main():
141 options, args = parse_options()
142
143 # Input IDL files are passed in a file, due to OS command line length
144 # limits. This is generated at GYP time, which is ok b/c files are static.
145 idl_files = read_file_to_list(options.idl_files_list)
146
147 # Output IDL files (to generate) are passed at the command line, since
148 # these are in the build directory, which is determined at build time, not
149 # GYP time.
150 # These are passed as pairs of GlobalObjectName, GlobalObject.idl
151 interface_name_idl_filename = [(args[i], args[i + 1])
152 for i in range(0, len(args), 2)]
153
154 with open(options.global_objects_file) as global_objects_file:
155 interface_name_to_global_names.update(pickle.load(global_objects_file))
156
157 for idl_filename in idl_files:
158 record_global_constructors(idl_filename)
159
160 # Check for [Exposed] / [Global] mismatch.
161 known_global_names = frozenset(itertools.chain.from_iterable(interface_name_ to_global_names.values()))
162 exposed_global_names = frozenset(global_name_to_constructors)
163 if not exposed_global_names.issubset(known_global_names):
164 unknown_global_names = exposed_global_names.difference(known_global_name s)
165 raise ValueError('The following global names were used in '
166 '[Exposed=xxx] but do not match any [Global] / '
167 '[PrimaryGlobal] interface: %s'
168 % list(unknown_global_names))
169
170 # Write partial interfaces containing constructor attributes for each
171 # global interface.
172 for interface_name, idl_filename in interface_name_idl_filename:
173 constructors = interface_name_to_constructors(interface_name)
174 write_global_constructors_partial_interface(
175 interface_name,
176 idl_filename,
177 constructors,
178 options.write_file_only_if_changed)
179
180
181 if __name__ == '__main__':
182 sys.exit(main())
OLDNEW
« no previous file with comments | « sky/engine/bindings/scripts/generate_event_interfaces.py ('k') | sky/engine/bindings/scripts/global_constructors.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698