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

Side by Side Diff: lib/html/scripts/databasebuilder.py

Issue 10987042: Speed up fremontcut/dartdomgenerator (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 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 | Annotate | Revision Log
« no previous file with comments | « lib/html/scripts/dartdomgenerator.py ('k') | lib/html/scripts/fremontcutbuilder.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 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a 3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file. 4 # BSD-style license that can be found in the LICENSE file.
5 5
6 import copy 6 import copy
7 import database 7 import database
8 import idlparser 8 import idlparser
9 import logging 9 import logging
10 import multiprocessing
10 import os 11 import os
11 import os.path 12 import os.path
12 import re 13 import re
13 14
14 from idlnode import * 15 from idlnode import *
15 16
16 _logger = logging.getLogger('databasebuilder') 17 _logger = logging.getLogger('databasebuilder')
17 18
18 # Used in source annotations to specify the parent interface declaring 19 # Used in source annotations to specify the parent interface declaring
19 # a displaced declaration. The 'via' attribute specifies the parent interface 20 # a displaced declaration. The 'via' attribute specifies the parent interface
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 self.source_attributes = source_attributes 57 self.source_attributes = source_attributes
57 self.idl_syntax = idl_syntax 58 self.idl_syntax = idl_syntax
58 self.idl_defines = idl_defines 59 self.idl_defines = idl_defines
59 self.type_rename_map = type_rename_map 60 self.type_rename_map = type_rename_map
60 self.rename_operation_arguments_on_merge = \ 61 self.rename_operation_arguments_on_merge = \
61 rename_operation_arguments_on_merge 62 rename_operation_arguments_on_merge
62 self.add_new_interfaces = add_new_interfaces 63 self.add_new_interfaces = add_new_interfaces
63 self.obsolete_old_declarations = obsolete_old_declarations 64 self.obsolete_old_declarations = obsolete_old_declarations
64 65
65 66
67 def _load_idl_file(file_name, import_options, result_queue):
68 """Loads an IDL file into memory"""
69 idl_parser = idlparser.IDLParser(import_options.idl_syntax)
70
71 try:
72 f = open(file_name, 'r')
73 content = f.read()
74 f.close()
75
76 idl_ast = idl_parser.parse(
77 content,
78 defines=import_options.idl_defines)
79 result = IDLFile(idl_ast, file_name)
80 result_queue.put(result, False)
81 return 0
82 except SyntaxError, e:
83 result_queue.put(RuntimeError('Failed to load file %s: %s'
84 % (file_name, e)),
85 False)
86 return 1
87 except:
88 result_queue.put('Unknown error loading %s' % file_name, False)
89 return 1
90
66 class DatabaseBuilder(object): 91 class DatabaseBuilder(object):
67 def __init__(self, database): 92 def __init__(self, database):
68 """DatabaseBuilder is used for importing and merging interfaces into 93 """DatabaseBuilder is used for importing and merging interfaces into
69 the Database""" 94 the Database"""
70 self._database = database 95 self._database = database
71 self._imported_interfaces = [] 96 self._imported_interfaces = []
72 self._impl_stmts = [] 97 self._impl_stmts = []
73 98
74 def _load_idl_file(self, file_name, import_options):
75 """Loads an IDL file intor memory"""
76 idl_parser = idlparser.IDLParser(import_options.idl_syntax)
77
78 try:
79 f = open(file_name, 'r')
80 content = f.read()
81 f.close()
82
83 idl_ast = idl_parser.parse(content,
84 defines=import_options.idl_defines)
85 return IDLFile(idl_ast, file_name)
86 except SyntaxError, e:
87 raise RuntimeError('Failed to load file %s: %s' % (file_name, e))
88
89 def _resolve_type_defs(self, idl_file): 99 def _resolve_type_defs(self, idl_file):
90 type_def_map = {} 100 type_def_map = {}
91 # build map 101 # build map
92 for type_def in idl_file.all(IDLTypeDef): 102 for type_def in idl_file.all(IDLTypeDef):
93 if type_def.type.id != type_def.id: # sanity check 103 if type_def.type.id != type_def.id: # sanity check
94 type_def_map[type_def.id] = type_def.type.id 104 type_def_map[type_def.id] = type_def.type.id
95 # use the map 105 # use the map
96 for type_node in idl_file.all(IDLType): 106 for type_node in idl_file.all(IDLType):
97 while type_node.id in type_def_map: 107 while type_node.id in type_def_map:
98 type_node.id = type_def_map[type_node.id] 108 type_node.id = type_def_map[type_node.id]
99 109
100 def _strip_ext_attributes(self, idl_file): 110 def _strip_ext_attributes(self, idl_file):
101 """Strips unuseful extended attributes.""" 111 """Strips unuseful extended attributes."""
102 for ext_attrs in idl_file.all(IDLExtAttrs): 112 for ext_attrs in idl_file.all(IDLExtAttrs):
103 # TODO: Decide which attributes are uninteresting. 113 # TODO: Decide which attributes are uninteresting.
104 pass 114 pass
105 115
106 def _rename_types(self, idl_file, import_options): 116 def _rename_types(self, idl_file, import_options):
107 """Rename interface and type names with names provided in the 117 """Rename interface and type names with names provided in the
108 options. Also clears scopes from scoped names""" 118 options. Also clears scopes from scoped names"""
109 119
110 def rename(name): 120 def rename(name):
111 name_parts = name.split('::') 121 name_parts = name.split('::')
112 name = name_parts[-1] 122 name = name_parts[-1]
113 if name in import_options.type_rename_map: 123 if name in import_options.type_rename_map:
114 name = import_options.type_rename_map[name] 124 name = import_options.type_rename_map[name]
115 return name 125 return name
116 126
117 def rename_node(idl_node): 127 def rename_node(idl_node):
118 idl_node.id = rename(idl_node.id) 128 idl_node.reset_id(rename(idl_node.id))
119 129
120 def rename_ext_attrs(ext_attrs_node): 130 def rename_ext_attrs(ext_attrs_node):
121 for type_valued_attribute_name in ['Supplemental']: 131 for type_valued_attribute_name in ['Supplemental']:
122 if type_valued_attribute_name in ext_attrs_node: 132 if type_valued_attribute_name in ext_attrs_node:
123 value = ext_attrs_node[type_valued_attribute_name] 133 value = ext_attrs_node[type_valued_attribute_name]
124 if isinstance(value, str): 134 if isinstance(value, str):
125 ext_attrs_node[type_valued_attribute_name] = rename(value) 135 ext_attrs_node[type_valued_attribute_name] = rename(value)
126 136
127 map(rename_node, idl_file.all(IDLInterface)) 137 map(rename_node, idl_file.all(IDLInterface))
128 map(rename_node, idl_file.all(IDLType)) 138 map(rename_node, idl_file.all(IDLType))
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 not new_interface.is_supplemental): 325 not new_interface.is_supplemental):
316 old_interface.annotations[source] = new_interface.annotations[source] 326 old_interface.annotations[source] = new_interface.annotations[source]
317 changed = True 327 changed = True
318 328
319 def merge_list(what): 329 def merge_list(what):
320 old_list = old_interface.__dict__[what] 330 old_list = old_interface.__dict__[what]
321 new_list = new_interface.__dict__[what] 331 new_list = new_interface.__dict__[what]
322 332
323 if what != 'parents' and old_interface.id != new_interface.id: 333 if what != 'parents' and old_interface.id != new_interface.id:
324 for node in new_list: 334 for node in new_list:
335 node.doc_js_interface_name = old_interface.id
325 node.ext_attrs['ImplementedBy'] = new_interface.id 336 node.ext_attrs['ImplementedBy'] = new_interface.id
326 337
327 changed = self._merge_nodes(old_list, new_list, import_options) 338 changed = self._merge_nodes(old_list, new_list, import_options)
328 339
329 # Delete list items with zero remaining annotations. 340 # Delete list items with zero remaining annotations.
330 if changed and import_options.obsolete_old_declarations: 341 if changed and import_options.obsolete_old_declarations:
331 342
332 def has_annotations(idl_node): 343 def has_annotations(idl_node):
333 return len(idl_node.annotations) 344 return len(idl_node.annotations)
334 345
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 else: 425 else:
415 raise Exception("Supplemental target '%s' not found", target) 426 raise Exception("Supplemental target '%s' not found", target)
416 427
417 # Step 4: Resolve 'implements' statements 428 # Step 4: Resolve 'implements' statements
418 for impl_stmt, import_options in self._impl_stmts: 429 for impl_stmt, import_options in self._impl_stmts:
419 self._merge_impl_stmt(impl_stmt, import_options) 430 self._merge_impl_stmt(impl_stmt, import_options)
420 431
421 self._impl_stmts = [] 432 self._impl_stmts = []
422 self._imported_interfaces = [] 433 self._imported_interfaces = []
423 434
424 def import_idl_file(self, file_path, 435 def import_idl_files(self, file_paths, import_options):
425 import_options=DatabaseBuilderOptions()): 436 # Parse the IDL files in parallel.
426 """Parses, loads into memory and cleans up and IDL file""" 437 result_queue = multiprocessing.Queue(len(file_paths))
427 idl_file = self._load_idl_file(file_path, import_options) 438 jobs = [ multiprocessing.Process(target=_load_idl_file,
439 args=(file_path, import_options,
440 result_queue))
441 for file_path in file_paths ]
442 try:
443 for job in jobs:
444 job.start()
445 for job in jobs:
446 # Timeout and throw after 5 sec.
447 result = result_queue.get(True, 5)
448 if isinstance(result, IDLFile):
449 self._process_idl_file(result, import_options)
450 else:
451 raise result
452 except:
453 # Clean up child processes on error.
454 for job in jobs:
455 job.terminate()
456 raise
428 457
458 def _process_idl_file(self, idl_file,
459 import_options):
429 self._strip_ext_attributes(idl_file) 460 self._strip_ext_attributes(idl_file)
430 self._resolve_type_defs(idl_file) 461 self._resolve_type_defs(idl_file)
431 self._rename_types(idl_file, import_options) 462 self._rename_types(idl_file, import_options)
432 463
433 def enabled(idl_node): 464 def enabled(idl_node):
434 return self._is_node_enabled(idl_node, import_options.idl_defines) 465 return self._is_node_enabled(idl_node, import_options.idl_defines)
435 466
436 for module in idl_file.modules: 467 for module in idl_file.modules:
437 for interface in module.interfaces: 468 for interface in module.interfaces:
438 if not self._is_node_enabled(interface, import_options.idl_defines): 469 if not self._is_node_enabled(interface, import_options.idl_defines):
439 _logger.info('skipping interface %s/%s (source=%s file=%s)' 470 _logger.info('skipping interface %s/%s (source=%s)'
440 % (module.id, interface.id, import_options.source, 471 % (module.id, interface.id, import_options.source))
441 file_path))
442 continue 472 continue
443 473
444 _logger.info('importing interface %s/%s (source=%s file=%s)' 474 _logger.info('importing interface %s/%s (source=%s)'
445 % (module.id, interface.id, import_options.source, 475 % (module.id, interface.id, import_options.source))
446 file_path))
447 interface.attributes = filter(enabled, interface.attributes) 476 interface.attributes = filter(enabled, interface.attributes)
448 interface.operations = filter(enabled, interface.operations) 477 interface.operations = filter(enabled, interface.operations)
449 self._imported_interfaces.append((interface, module.id, import_options)) 478 self._imported_interfaces.append((interface, module.id, import_options))
450 479
451 for implStmt in module.implementsStatements: 480 for implStmt in module.implementsStatements:
452 self._impl_stmts.append((implStmt, import_options)) 481 self._impl_stmts.append((implStmt, import_options))
453 482
454 def _is_node_enabled(self, node, idl_defines): 483 def _is_node_enabled(self, node, idl_defines):
455 if not 'Conditional' in node.ext_attrs: 484 if not 'Conditional' in node.ext_attrs:
456 return True 485 return True
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and fetch 579 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and fetch
551 # this information directly from it. Unfortunately right now database is massaged 580 # this information directly from it. Unfortunately right now database is massaged
552 # a lot so it's difficult to maintain necessary information on DOMWindow i tself. 581 # a lot so it's difficult to maintain necessary information on DOMWindow i tself.
553 interface = self._database.GetInterface(options.type_rename_map.get(type, type)) 582 interface = self._database.GetInterface(options.type_rename_map.get(type, type))
554 if 'V8EnabledPerContext' in attr.ext_attrs: 583 if 'V8EnabledPerContext' in attr.ext_attrs:
555 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ 584 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \
556 attr.ext_attrs['V8EnabledPerContext'] 585 attr.ext_attrs['V8EnabledPerContext']
557 if 'V8EnabledAtRuntime' in attr.ext_attrs: 586 if 'V8EnabledAtRuntime' in attr.ext_attrs:
558 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ 587 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \
559 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id 588 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id
OLDNEW
« no previous file with comments | « lib/html/scripts/dartdomgenerator.py ('k') | lib/html/scripts/fremontcutbuilder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698