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

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

Issue 670663002: IDL: Use IdlReader to compute interface_info_individual (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase Created 6 years, 2 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
« no previous file with comments | « Source/bindings/modules/generated.gyp ('k') | Source/bindings/scripts/idl_definitions.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 29 matching lines...) Expand all
40 40
41 Design doc: http://www.chromium.org/developers/design-documents/idl-build 41 Design doc: http://www.chromium.org/developers/design-documents/idl-build
42 """ 42 """
43 43
44 from collections import defaultdict 44 from collections import defaultdict
45 import optparse 45 import optparse
46 import os 46 import os
47 import posixpath 47 import posixpath
48 import sys 48 import sys
49 49
50 from utilities import get_file_contents, read_file_to_list, idl_filename_to_inte rface_name, idl_filename_to_component, write_pickle_file, get_interface_extended _attributes_from_idl, is_callback_interface_from_idl, is_dictionary_from_idl, ge t_partial_interface_name_from_idl, get_implements_from_idl, get_parent_interface , get_put_forward_interfaces_from_idl 50 from idl_reader import IdlReader
51 from utilities import get_file_contents, read_file_to_list, idl_filename_to_inte rface_name, idl_filename_to_component, write_pickle_file, get_interface_extended _attributes_from_idl, is_callback_interface_from_idl
51 52
52 module_path = os.path.dirname(__file__) 53 module_path = os.path.dirname(__file__)
53 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir)) 54 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir))
54 55
55 # Global variables (filled in and exported) 56 # Global variables (filled in and exported)
56 interfaces_info = {} 57 interfaces_info = {}
57 partial_interface_files = defaultdict(lambda: { 58 partial_interface_files = defaultdict(lambda: {
58 'full_paths': [], 59 'full_paths': [],
59 'include_paths': [], 60 'include_paths': [],
60 }) 61 })
61 62
62 63
64 class IdlBadFilenameError(Exception):
65 """Raised if an IDL filename disagrees with the interface name in the file." ""
66 pass
67
68
63 def parse_options(): 69 def parse_options():
64 usage = 'Usage: %prog [options] [generated1.idl]...' 70 usage = 'Usage: %prog [options] [generated1.idl]...'
65 parser = optparse.OptionParser(usage=usage) 71 parser = optparse.OptionParser(usage=usage)
72 parser.add_option('--cache-directory', help='cache directory')
66 parser.add_option('--idl-files-list', help='file listing IDL files') 73 parser.add_option('--idl-files-list', help='file listing IDL files')
67 parser.add_option('--interfaces-info-file', help='output pickle file') 74 parser.add_option('--interfaces-info-file', help='output pickle file')
68 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') 75 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')
69 76
70 options, args = parser.parse_args() 77 options, args = parser.parse_args()
71 if options.interfaces_info_file is None: 78 if options.interfaces_info_file is None:
72 parser.error('Must specify an output file using --interfaces-info-file.' ) 79 parser.error('Must specify an output file using --interfaces-info-file.' )
73 if options.idl_files_list is None: 80 if options.idl_files_list is None:
74 parser.error('Must specify a file listing IDL files using --idl-files-li st.') 81 parser.error('Must specify a file listing IDL files using --idl-files-li st.')
75 if options.write_file_only_if_changed is None: 82 if options.write_file_only_if_changed is None:
(...skipping 28 matching lines...) Expand all
104 return posixpath.join(relative_dir, cpp_class_name + '.h') 111 return posixpath.join(relative_dir, cpp_class_name + '.h')
105 112
106 113
107 def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_p ath=None): 114 def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_p ath=None):
108 paths_dict = partial_interface_files[partial_interface_name] 115 paths_dict = partial_interface_files[partial_interface_name]
109 paths_dict['full_paths'].append(full_path) 116 paths_dict['full_paths'].append(full_path)
110 if this_include_path: 117 if this_include_path:
111 paths_dict['include_paths'].append(this_include_path) 118 paths_dict['include_paths'].append(this_include_path)
112 119
113 120
114 def compute_info_individual(idl_filename): 121 def get_implements_from_definitions(definitions, definition_name):
122 left_interfaces = []
123 right_interfaces = []
124 for implement in definitions.implements:
125 if definition_name == implement.left_interface:
126 right_interfaces.append(implement.right_interface)
127 elif definition_name == implement.right_interface:
128 left_interfaces.append(implement.left_interface)
129 else:
130 raise IdlBadFilenameError(
131 'implements statement found in unrelated IDL file.\n'
132 'Statement is:\n'
133 ' %s implements %s;\n'
134 'but filename is unrelated "%s.idl"' %
135 (implement.left_interface, implement.right_interface, definition _name))
136 return left_interfaces, right_interfaces
137
138
139 def get_put_forward_interfaces_from_definition(definition):
140 return sorted(set(attribute.idl_type.base_type
141 for attribute in definition.attributes
142 if 'PutForwards' in attribute.extended_attributes))
143
144
145 def compute_info_individual(idl_filename, reader):
146 definitions = reader.read_idl_file(idl_filename)
147 if len(definitions.interfaces) > 0:
Nils Barth (inactive) 2014/10/22 14:19:51 Style nit: Use implicit true/false (truthy/falsy):
148 definition = next(definitions.interfaces.itervalues())
149 interface_info = {
150 'is_callback_interface': definition.is_callback,
151 'is_dictionary': False,
152 # Interfaces that are referenced (used as types) and that we introsp ect
153 # during code generation (beyond interface-level data ([ImplementedA s],
154 # is_callback_interface, ancestors, and inherited extended attribute s):
155 # deep dependencies.
156 # These cause rebuilds of referrers, due to the dependency, so these
157 # should be minimized; currently only targets of [PutForwards].
158 'referenced_interfaces': get_put_forward_interfaces_from_definition( definition),
159 }
160 elif len(definitions.dictionaries) > 0:
Nils Barth (inactive) 2014/10/22 14:19:52 Ditto.
161 definition = next(definitions.dictionaries.itervalues())
162 interface_info = {
163 'is_callback_interface': False,
164 'is_dictionary': True,
165 'referenced_interfaces': None,
166 }
167 else:
168 raise Exception('IDL file must contain one interface or dictionary')
169
170 extended_attributes = definition.extended_attributes
171 implemented_as = extended_attributes.get('ImplementedAs')
115 full_path = os.path.realpath(idl_filename) 172 full_path = os.path.realpath(idl_filename)
116 idl_file_contents = get_file_contents(full_path)
117
118 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co ntents)
119 implemented_as = extended_attributes.get('ImplementedAs')
120 relative_dir = relative_dir_posix(idl_filename)
121 this_include_path = None if 'NoImplHeader' in extended_attributes else inclu de_path(idl_filename, implemented_as) 173 this_include_path = None if 'NoImplHeader' in extended_attributes else inclu de_path(idl_filename, implemented_as)
122 174 if definition.is_partial:
123 # Handle partial interfaces 175 # We don't create interface_info for partial interfaces, but
124 partial_interface_name = get_partial_interface_name_from_idl(idl_file_conten ts) 176 # adds paths to another dict.
125 if partial_interface_name: 177 add_paths_to_partials_dict(definition.name, full_path, this_include_path )
126 add_paths_to_partials_dict(partial_interface_name, full_path, this_inclu de_path)
127 return 178 return
128 179
129 # If not a partial interface, the basename is the interface name
130 interface_name = idl_filename_to_interface_name(idl_filename)
131
132 # 'implements' statements can be included in either the file for the 180 # 'implements' statements can be included in either the file for the
133 # implement*ing* interface (lhs of 'implements') or implement*ed* interface 181 # implement*ing* interface (lhs of 'implements') or implement*ed* interface
134 # (rhs of 'implements'). Store both for now, then merge to implement*ing* 182 # (rhs of 'implements'). Store both for now, then merge to implement*ing*
135 # interface later. 183 # interface later.
136 left_interfaces, right_interfaces = get_implements_from_idl(idl_file_content s, interface_name) 184 left_interfaces, right_interfaces = get_implements_from_definitions(definiti ons, definition.name)
137 185
138 interfaces_info[interface_name] = { 186 interface_info.update({
139 'extended_attributes': extended_attributes, 187 'extended_attributes': extended_attributes,
140 'full_path': full_path, 188 'full_path': full_path,
141 'implemented_as': implemented_as, 189 'implemented_as': implemented_as,
142 'implemented_by_interfaces': left_interfaces, # private, merged to next 190 'implemented_by_interfaces': left_interfaces,
143 'implements_interfaces': right_interfaces, 191 'implements_interfaces': right_interfaces,
144 'include_path': this_include_path, 192 'include_path': this_include_path,
145 'is_callback_interface': is_callback_interface_from_idl(idl_file_content s),
146 'is_dictionary': is_dictionary_from_idl(idl_file_contents),
147 # FIXME: temporary private field, while removing old treatement of 193 # FIXME: temporary private field, while removing old treatement of
148 # 'implements': http://crbug.com/360435 194 # 'implements': http://crbug.com/360435
149 'is_legacy_treat_as_partial_interface': 'LegacyTreatAsPartialInterface' in extended_attributes, 195 'is_legacy_treat_as_partial_interface': 'LegacyTreatAsPartialInterface' in extended_attributes,
150 'parent': get_parent_interface(idl_file_contents), 196 'parent': definition.parent,
151 # Interfaces that are referenced (used as types) and that we introspect 197 'relative_dir': relative_dir_posix(idl_filename),
152 # during code generation (beyond interface-level data ([ImplementedAs], 198 })
153 # is_callback_interface, ancestors, and inherited extended attributes): 199 interfaces_info[definition.name] = interface_info
154 # deep dependencies.
155 # These cause rebuilds of referrers, due to the dependency, so these
156 # should be minimized; currently only targets of [PutForwards].
157 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co ntents),
158 'relative_dir': relative_dir,
159 }
160 200
161 201
162 def info_individual(): 202 def info_individual():
163 """Returns info packaged as a dict.""" 203 """Returns info packaged as a dict."""
164 return { 204 return {
165 'interfaces_info': interfaces_info, 205 'interfaces_info': interfaces_info,
166 # Can't pickle defaultdict, convert to dict 206 # Can't pickle defaultdict, convert to dict
167 'partial_interface_files': dict(partial_interface_files), 207 'partial_interface_files': dict(partial_interface_files),
168 } 208 }
169 209
170 210
171 ################################################################################ 211 ################################################################################
172 212
173 def main(): 213 def main():
174 options, args = parse_options() 214 options, args = parse_options()
175 215
176 # Static IDL files are passed in a file (generated at GYP time), due to OS 216 # Static IDL files are passed in a file (generated at GYP time), due to OS
177 # command line length limits 217 # command line length limits
178 idl_files = read_file_to_list(options.idl_files_list) 218 idl_files = read_file_to_list(options.idl_files_list)
179 # Generated IDL files are passed at the command line, since these are in the 219 # Generated IDL files are passed at the command line, since these are in the
180 # build directory, which is determined at build time, not GYP time, so these 220 # build directory, which is determined at build time, not GYP time, so these
181 # cannot be included in the file listing static files 221 # cannot be included in the file listing static files
182 idl_files.extend(args) 222 idl_files.extend(args)
183 223
184 # Compute information for individual files 224 # Compute information for individual files
185 # Information is stored in global variables interfaces_info and 225 # Information is stored in global variables interfaces_info and
186 # partial_interface_files. 226 # partial_interface_files.
227 reader = IdlReader(interfaces_info=None, outputdir=options.cache_directory)
187 for idl_filename in idl_files: 228 for idl_filename in idl_files:
188 compute_info_individual(idl_filename) 229 compute_info_individual(idl_filename, reader)
189 230
190 write_pickle_file(options.interfaces_info_file, 231 write_pickle_file(options.interfaces_info_file,
191 info_individual(), 232 info_individual(),
192 options.write_file_only_if_changed) 233 options.write_file_only_if_changed)
193 234
194 235
195 if __name__ == '__main__': 236 if __name__ == '__main__':
196 sys.exit(main()) 237 sys.exit(main())
OLDNEW
« no previous file with comments | « Source/bindings/modules/generated.gyp ('k') | Source/bindings/scripts/idl_definitions.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698