OLD | NEW |
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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 | 165 |
166 class InterfaceInfoCollector(object): | 166 class InterfaceInfoCollector(object): |
167 """A class that collects interface information from idl files.""" | 167 """A class that collects interface information from idl files.""" |
168 def __init__(self, cache_directory=None): | 168 def __init__(self, cache_directory=None): |
169 self.reader = IdlReader(interfaces_info=None, outputdir=cache_directory) | 169 self.reader = IdlReader(interfaces_info=None, outputdir=cache_directory) |
170 self.interfaces_info = {} | 170 self.interfaces_info = {} |
171 self.partial_interface_files = defaultdict(lambda: { | 171 self.partial_interface_files = defaultdict(lambda: { |
172 'full_paths': [], | 172 'full_paths': [], |
173 'include_paths': [], | 173 'include_paths': [], |
174 }) | 174 }) |
175 self.enumerations = set() | 175 self.enumerations = {} |
176 self.union_types = set() | 176 self.union_types = set() |
177 self.typedefs = {} | 177 self.typedefs = {} |
178 self.callback_functions = {} | 178 self.callback_functions = {} |
179 | 179 |
180 def add_paths_to_partials_dict(self, partial_interface_name, full_path, | 180 def add_paths_to_partials_dict(self, partial_interface_name, full_path, |
181 include_paths): | 181 include_paths): |
182 paths_dict = self.partial_interface_files[partial_interface_name] | 182 paths_dict = self.partial_interface_files[partial_interface_name] |
183 paths_dict['full_paths'].append(full_path) | 183 paths_dict['full_paths'].append(full_path) |
184 paths_dict['include_paths'].extend(include_paths) | 184 paths_dict['include_paths'].extend(include_paths) |
185 | 185 |
| 186 def check_enum_consistency(self, enum): |
| 187 existing_enum = self.enumerations.get(enum.name) |
| 188 if not existing_enum: |
| 189 return True |
| 190 # TODO(bashi): Ideally we should not allow multiple enum declarations |
| 191 # but we allow them to work around core/module separation. |
| 192 if len(existing_enum.values) != len(enum.values): |
| 193 return False |
| 194 return all(value in existing_enum.values for value in enum.values) |
| 195 |
186 def collect_info(self, idl_filename): | 196 def collect_info(self, idl_filename): |
187 """Reads an idl file and collects information which is required by the | 197 """Reads an idl file and collects information which is required by the |
188 binding code generation.""" | 198 binding code generation.""" |
189 def collect_unforgeable_attributes(definition, idl_filename): | 199 def collect_unforgeable_attributes(definition, idl_filename): |
190 """Collects [Unforgeable] attributes so that we can define them on | 200 """Collects [Unforgeable] attributes so that we can define them on |
191 sub-interfaces later. The resulting structure is as follows. | 201 sub-interfaces later. The resulting structure is as follows. |
192 interfaces_info[interface_name] = { | 202 interfaces_info[interface_name] = { |
193 'unforgeable_attributes': [IdlAttribute, ...], | 203 'unforgeable_attributes': [IdlAttribute, ...], |
194 ... | 204 ... |
195 } | 205 } |
(...skipping 19 matching lines...) Expand all Loading... |
215 self.union_types.update(this_union_types) | 225 self.union_types.update(this_union_types) |
216 self.typedefs.update(definitions.typedefs) | 226 self.typedefs.update(definitions.typedefs) |
217 for callback_function_name, callback_function in definitions.callback_fu
nctions.iteritems(): | 227 for callback_function_name, callback_function in definitions.callback_fu
nctions.iteritems(): |
218 # Set 'component_dir' to specify a directory that callback function
files belong to | 228 # Set 'component_dir' to specify a directory that callback function
files belong to |
219 self.callback_functions[callback_function_name] = { | 229 self.callback_functions[callback_function_name] = { |
220 'callback_function': callback_function, | 230 'callback_function': callback_function, |
221 'component_dir': idl_filename_to_component(idl_filename), | 231 'component_dir': idl_filename_to_component(idl_filename), |
222 'full_path': os.path.realpath(idl_filename), | 232 'full_path': os.path.realpath(idl_filename), |
223 } | 233 } |
224 # Check enum duplication. | 234 # Check enum duplication. |
225 for enum_name in definitions.enumerations.keys(): | 235 for enum in definitions.enumerations.values(): |
226 for defined_enum in self.enumerations: | 236 if not self.check_enum_consistency(enum): |
227 if defined_enum.name == enum_name: | 237 raise Exception('Enumeration "%s" is defined more than once ' |
228 raise Exception('Enumeration %s has multiple definitions' %
enum_name) | 238 'with different valid values' % enum.name) |
229 self.enumerations.update(definitions.enumerations.values()) | 239 self.enumerations.update(definitions.enumerations) |
230 | 240 |
231 if definitions.interfaces: | 241 if definitions.interfaces: |
232 definition = next(definitions.interfaces.itervalues()) | 242 definition = next(definitions.interfaces.itervalues()) |
233 interface_info = { | 243 interface_info = { |
234 'is_callback_interface': definition.is_callback, | 244 'is_callback_interface': definition.is_callback, |
235 'is_dictionary': False, | 245 'is_dictionary': False, |
236 # Interfaces that are referenced (used as types) and that we | 246 # Interfaces that are referenced (used as types) and that we |
237 # introspect during code generation (beyond interface-level | 247 # introspect during code generation (beyond interface-level |
238 # data ([ImplementedAs], is_callback_interface, ancestors, and | 248 # data ([ImplementedAs], is_callback_interface, ancestors, and |
239 # inherited extended attributes): deep dependencies. | 249 # inherited extended attributes): deep dependencies. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 # Can't pickle defaultdict, convert to dict | 327 # Can't pickle defaultdict, convert to dict |
318 # FIXME: this should be included in get_component_info. | 328 # FIXME: this should be included in get_component_info. |
319 'partial_interface_files': dict(self.partial_interface_files), | 329 'partial_interface_files': dict(self.partial_interface_files), |
320 } | 330 } |
321 | 331 |
322 def get_component_info_as_dict(self): | 332 def get_component_info_as_dict(self): |
323 """Returns component wide information as a dict.""" | 333 """Returns component wide information as a dict.""" |
324 return { | 334 return { |
325 'callback_functions': self.callback_functions, | 335 'callback_functions': self.callback_functions, |
326 'enumerations': dict((enum.name, enum.values) | 336 'enumerations': dict((enum.name, enum.values) |
327 for enum in self.enumerations), | 337 for enum in self.enumerations.values()), |
328 'typedefs': self.typedefs, | 338 'typedefs': self.typedefs, |
329 'union_types': self.union_types, | 339 'union_types': self.union_types, |
330 } | 340 } |
331 | 341 |
332 | 342 |
333 ################################################################################ | 343 ################################################################################ |
334 | 344 |
335 def main(): | 345 def main(): |
336 options, _ = parse_options() | 346 options, _ = parse_options() |
337 | 347 |
338 # IDL files are passed in a file, due to OS command line length limits | 348 # IDL files are passed in a file, due to OS command line length limits |
339 idl_files = read_idl_files_list_from_file(options.idl_files_list, is_gyp_for
mat=False) | 349 idl_files = read_idl_files_list_from_file(options.idl_files_list, is_gyp_for
mat=False) |
340 | 350 |
341 # Compute information for individual files | 351 # Compute information for individual files |
342 # Information is stored in global variables interfaces_info and | 352 # Information is stored in global variables interfaces_info and |
343 # partial_interface_files. | 353 # partial_interface_files. |
344 info_collector = InterfaceInfoCollector(options.cache_directory) | 354 info_collector = InterfaceInfoCollector(options.cache_directory) |
345 for idl_filename in idl_files: | 355 for idl_filename in idl_files: |
346 info_collector.collect_info(idl_filename) | 356 info_collector.collect_info(idl_filename) |
347 | 357 |
348 write_pickle_file(options.interfaces_info_file, | 358 write_pickle_file(options.interfaces_info_file, |
349 info_collector.get_info_as_dict()) | 359 info_collector.get_info_as_dict()) |
350 write_pickle_file(options.component_info_file, | 360 write_pickle_file(options.component_info_file, |
351 info_collector.get_component_info_as_dict()) | 361 info_collector.get_component_info_as_dict()) |
352 | 362 |
353 if __name__ == '__main__': | 363 if __name__ == '__main__': |
354 sys.exit(main()) | 364 sys.exit(main()) |
OLD | NEW |