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

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: PReserve old entrypoint 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(content,
Anton Muhin 2012/09/26 06:37:29 nit: unless it's against the style, maybe idl_pars
vsm 2012/09/26 16:22:10 Done.
77 defines=import_options.idl_defines)
78 result = IDLFile(idl_ast, file_name)
79 result_queue.put(result)
80 except SyntaxError, e:
81 raise RuntimeError('Failed to load file %s: %s' % (file_name, e))
Anton Muhin 2012/09/26 06:37:29 in multiprocessing, what would be result of throwi
vsm 2012/09/26 16:22:10 It'll quite the process, but the code below would
82
66 class DatabaseBuilder(object): 83 class DatabaseBuilder(object):
67 def __init__(self, database): 84 def __init__(self, database):
68 """DatabaseBuilder is used for importing and merging interfaces into 85 """DatabaseBuilder is used for importing and merging interfaces into
69 the Database""" 86 the Database"""
70 self._database = database 87 self._database = database
71 self._imported_interfaces = [] 88 self._imported_interfaces = []
72 self._impl_stmts = [] 89 self._impl_stmts = []
73 90
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): 91 def _resolve_type_defs(self, idl_file):
90 type_def_map = {} 92 type_def_map = {}
91 # build map 93 # build map
92 for type_def in idl_file.all(IDLTypeDef): 94 for type_def in idl_file.all(IDLTypeDef):
93 if type_def.type.id != type_def.id: # sanity check 95 if type_def.type.id != type_def.id: # sanity check
94 type_def_map[type_def.id] = type_def.type.id 96 type_def_map[type_def.id] = type_def.type.id
95 # use the map 97 # use the map
96 for type_node in idl_file.all(IDLType): 98 for type_node in idl_file.all(IDLType):
97 while type_node.id in type_def_map: 99 while type_node.id in type_def_map:
98 type_node.id = type_def_map[type_node.id] 100 type_node.id = type_def_map[type_node.id]
99 101
100 def _strip_ext_attributes(self, idl_file): 102 def _strip_ext_attributes(self, idl_file):
101 """Strips unuseful extended attributes.""" 103 """Strips unuseful extended attributes."""
102 for ext_attrs in idl_file.all(IDLExtAttrs): 104 for ext_attrs in idl_file.all(IDLExtAttrs):
103 # TODO: Decide which attributes are uninteresting. 105 # TODO: Decide which attributes are uninteresting.
104 pass 106 pass
105 107
106 def _rename_types(self, idl_file, import_options): 108 def _rename_types(self, idl_file, import_options):
107 """Rename interface and type names with names provided in the 109 """Rename interface and type names with names provided in the
108 options. Also clears scopes from scoped names""" 110 options. Also clears scopes from scoped names"""
109 111
110 def rename(name): 112 def rename(name):
111 name_parts = name.split('::') 113 name_parts = name.split('::')
112 name = name_parts[-1] 114 name = name_parts[-1]
113 if name in import_options.type_rename_map: 115 if name in import_options.type_rename_map:
114 name = import_options.type_rename_map[name] 116 name = import_options.type_rename_map[name]
115 return name 117 return name
116 118
117 def rename_node(idl_node): 119 def rename_node(idl_node):
118 idl_node.id = rename(idl_node.id) 120 new_name = rename(idl_node.id)
Anton Muhin 2012/09/26 06:37:29 why this change? does that belong to this CL?
vsm 2012/09/26 16:22:10 It turns out that writing a database to file and r
Anton Muhin 2012/09/26 17:53:09 Weird. Might be worth splitting those change if t
121 if new_name != idl_node.id:
122 idl_node.id = new_name
123 if isinstance(idl_node, IDLInterface):
124 idl_node.doc_js_name = new_name
125 idl_node.javascript_binding_name = new_name
126 for member in idl_node.operations:
127 member.doc_js_interface_name = new_name
128 for member in idl_node.attributes:
129 member.doc_js_interface_name = new_name
130 for member in idl_node.constants:
131 member.doc_js_interface_name = new_name
119 132
120 def rename_ext_attrs(ext_attrs_node): 133 def rename_ext_attrs(ext_attrs_node):
121 for type_valued_attribute_name in ['Supplemental']: 134 for type_valued_attribute_name in ['Supplemental']:
122 if type_valued_attribute_name in ext_attrs_node: 135 if type_valued_attribute_name in ext_attrs_node:
123 value = ext_attrs_node[type_valued_attribute_name] 136 value = ext_attrs_node[type_valued_attribute_name]
124 if isinstance(value, str): 137 if isinstance(value, str):
125 ext_attrs_node[type_valued_attribute_name] = rename(value) 138 ext_attrs_node[type_valued_attribute_name] = rename(value)
126 139
127 map(rename_node, idl_file.all(IDLInterface)) 140 map(rename_node, idl_file.all(IDLInterface))
128 map(rename_node, idl_file.all(IDLType)) 141 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): 328 not new_interface.is_supplemental):
316 old_interface.annotations[source] = new_interface.annotations[source] 329 old_interface.annotations[source] = new_interface.annotations[source]
317 changed = True 330 changed = True
318 331
319 def merge_list(what): 332 def merge_list(what):
320 old_list = old_interface.__dict__[what] 333 old_list = old_interface.__dict__[what]
321 new_list = new_interface.__dict__[what] 334 new_list = new_interface.__dict__[what]
322 335
323 if what != 'parents' and old_interface.id != new_interface.id: 336 if what != 'parents' and old_interface.id != new_interface.id:
324 for node in new_list: 337 for node in new_list:
338 node.doc_js_interface_name = old_interface.id
Anton Muhin 2012/09/26 06:37:29 ditto
vsm 2012/09/26 16:22:10 Same issue as above. On 2012/09/26 06:37:29, Anto
325 node.ext_attrs['ImplementedBy'] = new_interface.id 339 node.ext_attrs['ImplementedBy'] = new_interface.id
326 340
327 changed = self._merge_nodes(old_list, new_list, import_options) 341 changed = self._merge_nodes(old_list, new_list, import_options)
328 342
329 # Delete list items with zero remaining annotations. 343 # Delete list items with zero remaining annotations.
330 if changed and import_options.obsolete_old_declarations: 344 if changed and import_options.obsolete_old_declarations:
331 345
332 def has_annotations(idl_node): 346 def has_annotations(idl_node):
333 return len(idl_node.annotations) 347 return len(idl_node.annotations)
334 348
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 else: 428 else:
415 raise Exception("Supplemental target '%s' not found", target) 429 raise Exception("Supplemental target '%s' not found", target)
416 430
417 # Step 4: Resolve 'implements' statements 431 # Step 4: Resolve 'implements' statements
418 for impl_stmt, import_options in self._impl_stmts: 432 for impl_stmt, import_options in self._impl_stmts:
419 self._merge_impl_stmt(impl_stmt, import_options) 433 self._merge_impl_stmt(impl_stmt, import_options)
420 434
421 self._impl_stmts = [] 435 self._impl_stmts = []
422 self._imported_interfaces = [] 436 self._imported_interfaces = []
423 437
424 def import_idl_file(self, file_path, 438 def import_idl_files(self, file_paths, import_options):
439 # Parse the IDL files in parallel.
440 result_queue = multiprocessing.Queue()
441 jobs = [ multiprocessing.Process(target=_load_idl_file,
442 args=(file_path, import_options,
443 result_queue))
444 for file_path in file_paths ]
445 for job in jobs:
446 job.start()
447 for job in jobs:
448 result = result_queue.get()
Anton Muhin 2012/09/26 06:37:29 same question as above: if some of child processes
vsm 2012/09/26 16:22:10 PTAL. I've tested both bad IDL and timeout cases
449 self._process_idl_file(result, import_options)
450
451 def _process_idl_file(self, idl_file,
Anton Muhin 2012/09/26 06:37:29 should it be a method on its own or it might be a
vsm 2012/09/26 16:22:10 I've dropped the optional argument. It's not call
Anton Muhin 2012/09/26 17:57:26 I'd rather make it a closure of the only caller, b
425 import_options=DatabaseBuilderOptions()): 452 import_options=DatabaseBuilderOptions()):
426 """Parses, loads into memory and cleans up and IDL file"""
427 idl_file = self._load_idl_file(file_path, import_options)
428
429 self._strip_ext_attributes(idl_file) 453 self._strip_ext_attributes(idl_file)
430 self._resolve_type_defs(idl_file) 454 self._resolve_type_defs(idl_file)
431 self._rename_types(idl_file, import_options) 455 self._rename_types(idl_file, import_options)
432 456
433 def enabled(idl_node): 457 def enabled(idl_node):
434 return self._is_node_enabled(idl_node, import_options.idl_defines) 458 return self._is_node_enabled(idl_node, import_options.idl_defines)
435 459
436 for module in idl_file.modules: 460 for module in idl_file.modules:
437 for interface in module.interfaces: 461 for interface in module.interfaces:
438 if not self._is_node_enabled(interface, import_options.idl_defines): 462 if not self._is_node_enabled(interface, import_options.idl_defines):
439 _logger.info('skipping interface %s/%s (source=%s file=%s)' 463 _logger.info('skipping interface %s/%s (source=%s)'
440 % (module.id, interface.id, import_options.source, 464 % (module.id, interface.id, import_options.source))
441 file_path))
442 continue 465 continue
443 466
444 _logger.info('importing interface %s/%s (source=%s file=%s)' 467 _logger.info('importing interface %s/%s (source=%s)'
445 % (module.id, interface.id, import_options.source, 468 % (module.id, interface.id, import_options.source))
446 file_path))
447 interface.attributes = filter(enabled, interface.attributes) 469 interface.attributes = filter(enabled, interface.attributes)
448 interface.operations = filter(enabled, interface.operations) 470 interface.operations = filter(enabled, interface.operations)
449 self._imported_interfaces.append((interface, module.id, import_options)) 471 self._imported_interfaces.append((interface, module.id, import_options))
450 472
451 for implStmt in module.implementsStatements: 473 for implStmt in module.implementsStatements:
452 self._impl_stmts.append((implStmt, import_options)) 474 self._impl_stmts.append((implStmt, import_options))
453 475
454 def _is_node_enabled(self, node, idl_defines): 476 def _is_node_enabled(self, node, idl_defines):
455 if not 'Conditional' in node.ext_attrs: 477 if not 'Conditional' in node.ext_attrs:
456 return True 478 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 572 # 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 573 # 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. 574 # 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)) 575 interface = self._database.GetInterface(options.type_rename_map.get(type, type))
554 if 'V8EnabledPerContext' in attr.ext_attrs: 576 if 'V8EnabledPerContext' in attr.ext_attrs:
555 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ 577 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \
556 attr.ext_attrs['V8EnabledPerContext'] 578 attr.ext_attrs['V8EnabledPerContext']
557 if 'V8EnabledAtRuntime' in attr.ext_attrs: 579 if 'V8EnabledAtRuntime' in attr.ext_attrs:
558 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ 580 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \
559 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id 581 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