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

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

Issue 11114019: Switch to using IDLTypeInfo.interface_name(). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 | « no previous file | lib/html/scripts/systemnative.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) 2012, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2012, 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 """This module provides shared functionality for the system to generate 6 """This module provides shared functionality for the system to generate
7 Dart:html APIs from the IDL database.""" 7 Dart:html APIs from the IDL database."""
8 8
9 import emitter 9 import emitter
10 import os 10 import os
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 backend): 198 backend):
199 self._renamer = options.renamer 199 self._renamer = options.renamer
200 self._database = options.database 200 self._database = options.database
201 self._template_loader = options.templates 201 self._template_loader = options.templates
202 self._type_registry = options.type_registry 202 self._type_registry = options.type_registry
203 self._library_emitter = library_emitter 203 self._library_emitter = library_emitter
204 self._event_generator = event_generator 204 self._event_generator = event_generator
205 self._interface = interface 205 self._interface = interface
206 self._backend = backend 206 self._backend = backend
207 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) 207 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
208 self._html_interface_name = options.renamer.RenameInterface(self._interface)
209 208
210 def Generate(self): 209 def Generate(self):
211 if 'Callback' in self._interface.ext_attrs: 210 if 'Callback' in self._interface.ext_attrs:
212 self.GenerateCallback() 211 self.GenerateCallback()
213 else: 212 else:
214 self.GenerateInterface() 213 self.GenerateInterface()
215 214
216 def GenerateCallback(self): 215 def GenerateCallback(self):
217 """Generates a typedef for the callback interface.""" 216 """Generates a typedef for the callback interface."""
218 handlers = [operation for operation in self._interface.operations 217 handlers = [operation for operation in self._interface.operations
219 if operation.id == 'handleEvent'] 218 if operation.id == 'handleEvent']
220 info = AnalyzeOperation(self._interface, handlers) 219 info = AnalyzeOperation(self._interface, handlers)
221 code = self._library_emitter.FileEmitter(self._interface.id) 220 code = self._library_emitter.FileEmitter(self._interface.id)
222 code.Emit(self._template_loader.Load('callback.darttemplate')) 221 code.Emit(self._template_loader.Load('callback.darttemplate'))
223 code.Emit('typedef $TYPE $NAME($PARAMS);\n', 222 code.Emit('typedef $TYPE $NAME($PARAMS);\n',
224 NAME=self._interface.id, 223 NAME=self._interface.id,
225 TYPE=self._DartType(info.type_name), 224 TYPE=self._DartType(info.type_name),
226 PARAMS=info.ParametersImplementationDeclaration(self._DartType)) 225 PARAMS=info.ParametersImplementationDeclaration(self._DartType))
227 self._backend.GenerateCallback(info) 226 self._backend.GenerateCallback(info)
228 227
229 def GenerateInterface(self): 228 def GenerateInterface(self):
229 interface_name = self._interface_type_info.interface_name()
230
230 if (self._interface_type_info.has_generated_interface() and 231 if (self._interface_type_info.has_generated_interface() and
231 not self._interface_type_info.merged_into()): 232 not self._interface_type_info.merged_into()):
232 interface_emitter = self._library_emitter.FileEmitter( 233 interface_emitter = self._library_emitter.FileEmitter(interface_name)
233 self._html_interface_name)
234 else: 234 else:
235 interface_emitter = emitter.Emitter() 235 interface_emitter = emitter.Emitter()
236 236
237 template_file = 'interface_%s.darttemplate' % self._html_interface_name 237 template_file = 'interface_%s.darttemplate' % interface_name
238 interface_template = (self._template_loader.TryLoad(template_file) or 238 interface_template = (self._template_loader.TryLoad(template_file) or
239 self._template_loader.Load('interface.darttemplate')) 239 self._template_loader.Load('interface.darttemplate'))
240 240
241 typename = self._html_interface_name
242
243 implements = [] 241 implements = []
244 suppressed_implements = [] 242 suppressed_implements = []
245 243
246 for parent in self._interface.parents: 244 for parent in self._interface.parents:
247 parent_type_info = self._type_registry.TypeInfo(parent.type.id) 245 parent_type_info = self._type_registry.TypeInfo(parent.type.id)
248 parent_interface_name = parent_type_info.interface_name() 246 parent_interface_name = parent_type_info.interface_name()
249 # TODO(vsm): Remove source_filter. 247 # TODO(vsm): Remove source_filter.
250 if MatchSourceFilter(parent): 248 if MatchSourceFilter(parent):
251 # Parent is a DOM type. 249 # Parent is a DOM type.
252 implements.append(parent_interface_name) 250 implements.append(parent_interface_name)
253 elif '<' in parent.type.id: 251 elif '<' in parent.type.id:
254 # Parent is a Dart collection type. 252 # Parent is a Dart collection type.
255 # TODO(vsm): Make this check more robust. 253 # TODO(vsm): Make this check more robust.
256 implements.append(parent_interface_name) 254 implements.append(parent_interface_name)
257 else: 255 else:
258 suppressed_implements.append('%s.%s' % 256 suppressed_implements.append('%s.%s' %
259 (self._common_prefix, parent_interface_name)) 257 (self._common_prefix, parent_interface_name))
260 258
261 if typename in _secure_base_types: 259 if interface_name in _secure_base_types:
262 implements.append(_secure_base_types[typename]) 260 implements.append(_secure_base_types[interface_name])
263 261
264 comment = ' extends' 262 comment = ' extends'
265 implements_str = '' 263 implements_str = ''
266 if implements: 264 if implements:
267 implements_str += ' implements ' + ', '.join(implements) 265 implements_str += ' implements ' + ', '.join(implements)
268 comment = ',' 266 comment = ','
269 if suppressed_implements: 267 if suppressed_implements:
270 implements_str += ' /*%s %s */' % (comment, 268 implements_str += ' /*%s %s */' % (comment,
271 ', '.join(suppressed_implements)) 269 ', '.join(suppressed_implements))
272 270
273 factory_provider = None 271 factory_provider = None
274 if typename in interface_factories: 272 if interface_name in interface_factories:
275 factory_provider = interface_factories[typename] 273 factory_provider = interface_factories[interface_name]
276 274
277 constructors = [] 275 constructors = []
278 constructor_info = AnalyzeConstructor(self._interface) 276 constructor_info = AnalyzeConstructor(self._interface)
279 if constructor_info: 277 if constructor_info:
280 constructors.append(constructor_info) 278 constructors.append(constructor_info)
281 factory_provider = '_' + typename + 'FactoryProvider' 279 factory_provider = '_' + interface_name + 'FactoryProvider'
282 factory_provider_emitter = self._library_emitter.FileEmitter( 280 factory_provider_emitter = self._library_emitter.FileEmitter(
283 '_%sFactoryProvider' % self._html_interface_name) 281 '_%sFactoryProvider' % interface_name)
284 self._backend.EmitFactoryProvider( 282 self._backend.EmitFactoryProvider(
285 constructor_info, factory_provider, factory_provider_emitter) 283 constructor_info, factory_provider, factory_provider_emitter)
286 284
287 infos = HtmlElementConstructorInfos(typename) 285 infos = HtmlElementConstructorInfos(interface_name)
288 if infos: 286 if infos:
289 template = self._template_loader.Load( 287 template = self._template_loader.Load(
290 'factoryprovider_Elements.darttemplate') 288 'factoryprovider_Elements.darttemplate')
291 EmitHtmlElementFactoryConstructors( 289 EmitHtmlElementFactoryConstructors(
292 self._library_emitter.FileEmitter('_Elements', template), 290 self._library_emitter.FileEmitter('_Elements', template),
293 infos, 291 infos,
294 self._interface.id, 292 self._interface.id,
295 self._backend.ImplementationClassName(), 293 self._backend.ImplementationClassName(),
296 self._DartType) 294 self._DartType)
297 295
298 for info in infos: 296 for info in infos:
299 constructors.append(info.ConstructorInfo(self._interface.id)) 297 constructors.append(info.ConstructorInfo(self._interface.id))
300 if factory_provider: 298 if factory_provider:
301 assert factory_provider == info.factory_provider_name 299 assert factory_provider == info.factory_provider_name
302 else: 300 else:
303 factory_provider = info.factory_provider_name 301 factory_provider = info.factory_provider_name
304 302
305 # TODO(vsm): Add appropriate package / namespace syntax. 303 # TODO(vsm): Add appropriate package / namespace syntax.
306 (self._type_comment_emitter, 304 (self._type_comment_emitter,
307 self._members_emitter, 305 self._members_emitter,
308 self._top_level_emitter) = interface_emitter.Emit( 306 self._top_level_emitter) = interface_emitter.Emit(
309 interface_template + '$!TOP_LEVEL', 307 interface_template + '$!TOP_LEVEL',
310 ID=typename, 308 ID=interface_name,
311 EXTENDS=implements_str) 309 EXTENDS=implements_str)
312 310
313 self._type_comment_emitter.Emit("/// @domName $DOMNAME", 311 self._type_comment_emitter.Emit("/// @domName $DOMNAME",
314 DOMNAME=self._interface.doc_js_name) 312 DOMNAME=self._interface.doc_js_name)
315 313
316 implementation_emitter = self._ImplementationEmitter() 314 implementation_emitter = self._ImplementationEmitter()
317 base_class = self._backend.BaseClassName() 315 base_class = self._backend.BaseClassName()
318 interface_type_info = self._type_registry.TypeInfo(self._interface.id) 316 interface_type_info = self._type_registry.TypeInfo(self._interface.id)
319 implemented_interfaces = [interface_type_info.interface_name()] +\ 317 implemented_interfaces = [interface_type_info.interface_name()] +\
320 self._backend.AdditionalImplementedInterfaces() 318 self._backend.AdditionalImplementedInterfaces()
(...skipping 20 matching lines...) Expand all
341 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' 339 ' factory $CTOR.fromList(List<$TYPE> list) =>\n'
342 ' $FACTORY.create$(CTOR)_fromList(list);\n' 340 ' $FACTORY.create$(CTOR)_fromList(list);\n'
343 '\n' 341 '\n'
344 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l ength]) => \n' 342 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l ength]) => \n'
345 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n' , 343 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n' ,
346 CTOR=self._interface.id, 344 CTOR=self._interface.id,
347 TYPE=self._DartType(element_type), 345 TYPE=self._DartType(element_type),
348 FACTORY=factory_provider) 346 FACTORY=factory_provider)
349 347
350 events_interface = self._event_generator.ProcessInterface( 348 events_interface = self._event_generator.ProcessInterface(
351 self._interface, self._html_interface_name, 349 self._interface, interface_name,
352 self._backend.CustomJSMembers(), 350 self._backend.CustomJSMembers(),
353 interface_emitter, implementation_emitter) 351 interface_emitter, implementation_emitter)
354 if events_interface: 352 if events_interface:
355 self._EmitEventGetter(events_interface, '_%sImpl' % events_interface) 353 self._EmitEventGetter(events_interface, '_%sImpl' % events_interface)
356 354
357 old_backend = self._backend 355 old_backend = self._backend
358 if not self._backend.ImplementsMergedMembers(): 356 if not self._backend.ImplementsMergedMembers():
359 self._backend = HtmlGeneratorDummyBackend() 357 self._backend = HtmlGeneratorDummyBackend()
360 merged_interface = self._interface_type_info.merged_interface() 358 merged_interface = self._interface_type_info.merged_interface()
361 if merged_interface: 359 if merged_interface:
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) 502 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
505 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', 503 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
506 NAME=constant.id, 504 NAME=constant.id,
507 TYPE=type, 505 TYPE=type,
508 VALUE=constant.value) 506 VALUE=constant.value)
509 507
510 def _ImplementationEmitter(self): 508 def _ImplementationEmitter(self):
511 if IsPureInterface(self._interface.id): 509 if IsPureInterface(self._interface.id):
512 return emitter.Emitter() 510 return emitter.Emitter()
513 511
514 if not self._interface_type_info.merged_into(): 512 basename = self._interface_type_info.implementation_name()
515 name = self._html_interface_name 513 if self._interface_type_info.merged_into():
516 basename = '%sImpl' % name
517 else:
518 if self._backend.ImplementsMergedMembers(): 514 if self._backend.ImplementsMergedMembers():
519 # Merged members are implemented in target interface implementation. 515 # Merged members are implemented in target interface implementation.
520 return emitter.Emitter() 516 return emitter.Emitter()
521 basename = '%sImpl_Merged' % self._html_interface_name 517 basename = '%s_Merged' % basename
522 return self._library_emitter.FileEmitter(basename) 518 return self._library_emitter.FileEmitter(basename.lstrip('_'))
523 519
524 def _EmitEventGetter(self, events_interface, events_class): 520 def _EmitEventGetter(self, events_interface, events_class):
525 self._members_emitter.Emit( 521 self._members_emitter.Emit(
526 '\n /**' 522 '\n /**'
527 '\n * @domName EventTarget.addEventListener, ' 523 '\n * @domName EventTarget.addEventListener, '
528 'EventTarget.removeEventListener, EventTarget.dispatchEvent' 524 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
529 '\n */' 525 '\n */'
530 '\n $TYPE get on;\n', 526 '\n $TYPE get on;\n',
531 TYPE=events_interface) 527 TYPE=events_interface)
532 528
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 """Generates a dart2js class for the dart:html library from a DOM IDL 576 """Generates a dart2js class for the dart:html library from a DOM IDL
581 interface. 577 interface.
582 """ 578 """
583 579
584 def __init__(self, interface, options): 580 def __init__(self, interface, options):
585 self._interface = interface 581 self._interface = interface
586 self._database = options.database 582 self._database = options.database
587 self._template_loader = options.templates 583 self._template_loader = options.templates
588 self._type_registry = options.type_registry 584 self._type_registry = options.type_registry
589 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) 585 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
590 self._html_interface_name = options.renamer.RenameInterface(self._interface)
591 self._current_secondary_parent = None 586 self._current_secondary_parent = None
592 587
593 def ImplementationClassName(self): 588 def ImplementationClassName(self):
594 return self._ImplClassName(self._html_interface_name) 589 return self._interface_type_info.implementation_name()
595 590
596 def ImplementsMergedMembers(self): 591 def ImplementsMergedMembers(self):
597 return True 592 return True
598 593
599 def _ImplClassName(self, type_name):
600 return '_%sImpl' % type_name
601
602 def GenerateCallback(self, info): 594 def GenerateCallback(self, info):
603 pass 595 pass
604 596
605 def BaseClassName(self): 597 def BaseClassName(self):
606 if not self._interface.parents: 598 if not self._interface.parents:
607 return None 599 return None
608 supertype = self._interface.parents[0].type.id 600 supertype = self._interface.parents[0].type.id
609 if IsDartCollectionType(supertype): 601 if IsDartCollectionType(supertype):
610 # List methods are injected in AddIndexer. 602 # List methods are injected in AddIndexer.
611 return None 603 return None
612 if IsPureInterface(supertype): 604 if IsPureInterface(supertype):
613 return None 605 return None
614 return self._type_registry.TypeInfo(supertype).implementation_name() 606 return self._type_registry.TypeInfo(supertype).implementation_name()
615 607
616 def AdditionalImplementedInterfaces(self): 608 def AdditionalImplementedInterfaces(self):
617 # TODO: Include all implemented interfaces, including other Lists. 609 # TODO: Include all implemented interfaces, including other Lists.
618 implements = [] 610 implements = []
619 element_type = MaybeTypedArrayElementType(self._interface) 611 element_type = MaybeTypedArrayElementType(self._interface)
620 if element_type: 612 if element_type:
621 implements.append('List<%s>' % self._DartType(element_type)) 613 implements.append('List<%s>' % self._DartType(element_type))
622 if self._HasJavaScriptIndexingBehaviour(): 614 if self._HasJavaScriptIndexingBehaviour():
623 implements.append('JavaScriptIndexingBehavior') 615 implements.append('JavaScriptIndexingBehavior')
624 return implements 616 return implements
625 617
626 def NativeSpec(self): 618 def NativeSpec(self):
627 native_spec = MakeNativeSpec(self._interface.javascript_binding_name) 619 native_spec = MakeNativeSpec(self._interface.javascript_binding_name)
628 return ' native "%s"' % native_spec 620 return ' native "%s"' % native_spec
629 621
630 def ImplementationTemplate(self): 622 def ImplementationTemplate(self):
631 template_file = 'impl_%s.darttemplate' % self._html_interface_name 623 template_file = ('impl_%s.darttemplate' %
624 self._interface_type_info.interface_name())
632 return (self._template_loader.TryLoad(template_file) or 625 return (self._template_loader.TryLoad(template_file) or
633 self._template_loader.Load('dart2js_impl.darttemplate')) 626 self._template_loader.Load('dart2js_impl.darttemplate'))
634 627
635 def StartInterface(self, emitter): 628 def StartInterface(self, emitter):
636 self._members_emitter = emitter 629 self._members_emitter = emitter
637 630
638 def FinishInterface(self): 631 def FinishInterface(self):
639 pass 632 pass
640 633
641 def EmitFactoryProvider(self, constructor_info, factory_provider, emitter): 634 def EmitFactoryProvider(self, constructor_info, factory_provider, emitter):
642 template_file = ('factoryprovider_%s.darttemplate' % 635 template_file = ('factoryprovider_%s.darttemplate' %
643 self._html_interface_name) 636 self._interface_type_info.interface_name())
644 template = self._template_loader.TryLoad(template_file) 637 template = self._template_loader.TryLoad(template_file)
645 if not template: 638 if not template:
646 template = self._template_loader.Load('factoryprovider.darttemplate') 639 template = self._template_loader.Load('factoryprovider.darttemplate')
647 640
641 interface_name = self._interface_type_info.interface_name()
648 emitter.Emit( 642 emitter.Emit(
649 template, 643 template,
650 FACTORYPROVIDER=factory_provider, 644 FACTORYPROVIDER=factory_provider,
651 CONSTRUCTOR=self._html_interface_name, 645 CONSTRUCTOR=interface_name,
652 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da rtType), 646 PARAMETERS=constructor_info.ParametersImplementationDeclaration(self._Da rtType),
653 NAMED_CONSTRUCTOR=constructor_info.name or self._html_interface_name, 647 NAMED_CONSTRUCTOR=constructor_info.name or interface_name,
654 ARGUMENTS=constructor_info.ParametersAsArgumentList()) 648 ARGUMENTS=constructor_info.ParametersAsArgumentList())
655 649
656 def SecondaryContext(self, interface): 650 def SecondaryContext(self, interface):
657 if interface is not self._current_secondary_parent: 651 if interface is not self._current_secondary_parent:
658 self._current_secondary_parent = interface 652 self._current_secondary_parent = interface
659 self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id) 653 self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id)
660 654
661 def AddIndexer(self, element_type): 655 def AddIndexer(self, element_type):
662 """Adds all the methods required to complete implementation of List.""" 656 """Adds all the methods required to complete implementation of List."""
663 # We would like to simply inherit the implementation of everything except 657 # We would like to simply inherit the implementation of everything except
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 return any(self._InputConversion(arg.type.id, operation.id) 1005 return any(self._InputConversion(arg.type.id, operation.id)
1012 for arg in operation.arguments) 1006 for arg in operation.arguments)
1013 1007
1014 def _OutputConversion(self, idl_type, member): 1008 def _OutputConversion(self, idl_type, member):
1015 return FindConversion(idl_type, 'get', self._interface.id, member) 1009 return FindConversion(idl_type, 'get', self._interface.id, member)
1016 1010
1017 def _InputConversion(self, idl_type, member): 1011 def _InputConversion(self, idl_type, member):
1018 return FindConversion(idl_type, 'set', self._interface.id, member) 1012 return FindConversion(idl_type, 'set', self._interface.id, member)
1019 1013
1020 def _HasCustomImplementation(self, member_name): 1014 def _HasCustomImplementation(self, member_name):
1021 member_name = '%s.%s' % (self._html_interface_name, member_name) 1015 member_name = '%s.%s' % (self._interface_type_info.interface_name(),
1016 member_name)
1022 return member_name in _js_custom_members 1017 return member_name in _js_custom_members
1023 1018
1024 def CustomJSMembers(self): 1019 def CustomJSMembers(self):
1025 return _js_custom_members 1020 return _js_custom_members
1026 1021
1027 def _HasJavaScriptIndexingBehaviour(self): 1022 def _HasJavaScriptIndexingBehaviour(self):
1028 """Returns True if the native object has an indexer and length property.""" 1023 """Returns True if the native object has an indexer and length property."""
1029 (element_type, requires_indexer) = ListImplementationInfo( 1024 (element_type, requires_indexer) = ListImplementationInfo(
1030 self._interface, self._database) 1025 self._interface, self._database)
1031 if element_type and requires_indexer: return True 1026 if element_type and requires_indexer: return True
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 1102
1108 library_emitter = self._multiemitter.FileEmitter(library_file_path) 1103 library_emitter = self._multiemitter.FileEmitter(library_file_path)
1109 library_file_dir = os.path.dirname(library_file_path) 1104 library_file_dir = os.path.dirname(library_file_path)
1110 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) 1105 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir)
1111 imports_emitter = library_emitter.Emit( 1106 imports_emitter = library_emitter.Emit(
1112 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) 1107 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir))
1113 for path in sorted(self._path_to_emitter.keys()): 1108 for path in sorted(self._path_to_emitter.keys()):
1114 relpath = os.path.relpath(path, library_file_dir) 1109 relpath = os.path.relpath(path, library_file_dir)
1115 imports_emitter.Emit( 1110 imports_emitter.Emit(
1116 "#source('$PATH');\n", PATH=massage_path(relpath)) 1111 "#source('$PATH');\n", PATH=massage_path(relpath))
OLDNEW
« no previous file with comments | « no previous file | lib/html/scripts/systemnative.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698