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

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

Issue 11365019: Merging dart:html interfaces and implementations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixing merged classes in dartium not compiling under dartc. Created 8 years, 1 month 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 | « sdk/lib/html/scripts/htmleventgenerator.py ('k') | sdk/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
11 from generator import * 11 from generator import *
12 from htmldartgenerator import *
12 13
13 _js_custom_members = set([ 14 _js_custom_members = set([
14 'AudioBufferSourceNode.start', 15 'AudioBufferSourceNode.start',
15 'AudioBufferSourceNode.stop', 16 'AudioBufferSourceNode.stop',
16 'AudioContext.createGain', 17 'AudioContext.createGain',
17 'AudioContext.createScriptProcessor', 18 'AudioContext.createScriptProcessor',
18 'CSSStyleDeclaration.setProperty', 19 'CSSStyleDeclaration.setProperty',
19 'Element.insertAdjacentElement', 20 'Element.insertAdjacentElement',
20 'Element.insertAdjacentHTML', 21 'Element.insertAdjacentHTML',
21 'Element.insertAdjacentText', 22 'Element.insertAdjacentText',
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 return infos 182 return infos
182 183
183 def EmitHtmlElementFactoryConstructors(emitter, infos, typename, class_name, 184 def EmitHtmlElementFactoryConstructors(emitter, infos, typename, class_name,
184 rename_type): 185 rename_type):
185 for info in infos: 186 for info in infos:
186 constructor_info = info.ConstructorInfo(typename) 187 constructor_info = info.ConstructorInfo(typename)
187 188
188 inits = emitter.Emit( 189 inits = emitter.Emit(
189 '\n' 190 '\n'
190 ' static $RETURN_TYPE $CONSTRUCTOR($PARAMS) {\n' 191 ' static $RETURN_TYPE $CONSTRUCTOR($PARAMS) {\n'
191 ' $CLASS _e = _document.$dom_createElement("$TAG");\n' 192 ' $CLASS _e = document.$dom_createElement("$TAG");\n'
192 '$!INITS' 193 '$!INITS'
193 ' return _e;\n' 194 ' return _e;\n'
194 ' }\n', 195 ' }\n',
195 RETURN_TYPE=rename_type(constructor_info.type_name), 196 RETURN_TYPE=rename_type(constructor_info.type_name),
196 CONSTRUCTOR=constructor_info.ConstructorFactoryName(rename_type), 197 CONSTRUCTOR=constructor_info.ConstructorFactoryName(rename_type),
197 CLASS=class_name, 198 CLASS=class_name,
198 TAG=info.tag, 199 TAG=info.tag,
199 PARAMS=constructor_info.ParametersDeclaration( 200 PARAMS=constructor_info.ParametersDeclaration(
200 rename_type, force_optional=True)) 201 rename_type, force_optional=True))
201 for param in constructor_info.param_infos: 202 for param in constructor_info.param_infos:
(...skipping 30 matching lines...) Expand all
232 code = self._library_emitter.FileEmitter(self._interface.id) 233 code = self._library_emitter.FileEmitter(self._interface.id)
233 code.Emit(self._template_loader.Load('callback.darttemplate')) 234 code.Emit(self._template_loader.Load('callback.darttemplate'))
234 code.Emit('typedef void $NAME($PARAMS);\n', 235 code.Emit('typedef void $NAME($PARAMS);\n',
235 NAME=self._interface.id, 236 NAME=self._interface.id,
236 PARAMS=info.ParametersDeclaration(self._DartType)) 237 PARAMS=info.ParametersDeclaration(self._DartType))
237 self._backend.GenerateCallback(info) 238 self._backend.GenerateCallback(info)
238 239
239 def GenerateInterface(self): 240 def GenerateInterface(self):
240 interface_name = self._interface_type_info.interface_name() 241 interface_name = self._interface_type_info.interface_name()
241 242
242 if (self._interface_type_info.has_generated_interface() and 243 # TODO: this is just tossing the interface, need to skip it completely.
243 not self._interface_type_info.merged_into()): 244 interface_emitter = emitter.Emitter()
244 interface_emitter = self._library_emitter.FileEmitter(interface_name)
245 else:
246 interface_emitter = emitter.Emitter()
247 245
248 template_file = 'interface_%s.darttemplate' % interface_name 246 template_file = 'interface_%s.darttemplate' % interface_name
249 interface_template = (self._template_loader.TryLoad(template_file) or 247 interface_template = (self._template_loader.TryLoad(template_file) or
250 self._template_loader.Load('interface.darttemplate')) 248 self._template_loader.Load('interface.darttemplate'))
251 249
252 implements = [] 250 implements = []
253 for parent in self._interface.parents: 251 for parent in self._interface.parents:
254 parent_type_info = self._type_registry.TypeInfo(parent.type.id) 252 parent_type_info = self._type_registry.TypeInfo(parent.type.id)
255 implements.append(parent_type_info.interface_name()) 253 implements.append(parent_type_info.interface_name())
256 254
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 if factory_provider: 299 if factory_provider:
302 assert factory_provider == info.factory_provider_name 300 assert factory_provider == info.factory_provider_name
303 else: 301 else:
304 factory_provider = info.factory_provider_name 302 factory_provider = info.factory_provider_name
305 303
306 # TODO(vsm): Add appropriate package / namespace syntax. 304 # TODO(vsm): Add appropriate package / namespace syntax.
307 (self._type_comment_emitter, 305 (self._type_comment_emitter,
308 self._members_emitter, 306 self._members_emitter,
309 self._top_level_emitter) = interface_emitter.Emit( 307 self._top_level_emitter) = interface_emitter.Emit(
310 interface_template + '$!TOP_LEVEL', 308 interface_template + '$!TOP_LEVEL',
311 ID=interface_name, 309 ID='_I%s' % interface_name,
312 EXTENDS=implements_str) 310 EXTENDS=implements_str)
313 311
314 self._type_comment_emitter.Emit("/// @domName $DOMNAME",
315 DOMNAME=self._interface.doc_js_name)
316
317 implementation_emitter = self._ImplementationEmitter() 312 implementation_emitter = self._ImplementationEmitter()
318 313
319 base_class = self._backend.RootClassName() 314 base_type_info = None
320 if self._interface.parents: 315 if self._interface.parents:
321 supertype = self._interface.parents[0].type.id 316 supertype = self._interface.parents[0].type.id
322 if not IsDartCollectionType(supertype) and not IsPureInterface(supertype): 317 if not IsDartCollectionType(supertype) and not IsPureInterface(supertype):
323 type_info = self._type_registry.TypeInfo(supertype) 318 base_type_info = self._type_registry.TypeInfo(supertype)
324 if type_info.merged_into() and self._backend.ImplementsMergedMembers(): 319 if base_type_info.merged_into() \
325 type_info = self._type_registry.TypeInfo(type_info.merged_into()) 320 and self._backend.ImplementsMergedMembers():
326 base_class = type_info.implementation_name() 321 base_type_info = self._type_registry.TypeInfo(
322 base_type_info.merged_into())
327 323
328 implemented_interfaces = [interface_name] +\ 324 if base_type_info:
329 self._backend.AdditionalImplementedInterfaces() 325 base_class = base_type_info.implementation_name()
326 else:
327 base_class = self._backend.RootClassName()
328
329 implements = self._backend.AdditionalImplementedInterfaces()
330 for parent in self._interface.parents:
331 parent_type_info = self._type_registry.TypeInfo(parent.type.id)
332 if parent_type_info != base_type_info:
333 implements.append(parent_type_info.interface_name())
334
335 if interface_name in _secure_base_types:
336 implements.append(_secure_base_types[interface_name])
337
338 implements_str = ''
339 if implements:
340 implements_str = ' implements ' + ', '.join(set(implements))
341
330 self._implementation_members_emitter = implementation_emitter.Emit( 342 self._implementation_members_emitter = implementation_emitter.Emit(
331 self._backend.ImplementationTemplate(), 343 self._backend.ImplementationTemplate(),
332 CLASSNAME=self._interface_type_info.implementation_name(), 344 CLASSNAME=self._interface_type_info.implementation_name(),
333 EXTENDS=' extends %s' % base_class if base_class else '', 345 EXTENDS=' extends %s' % base_class if base_class else '',
334 IMPLEMENTS=' implements ' + ', '.join(implemented_interfaces), 346 IMPLEMENTS=implements_str,
347 DOMNAME=self._interface.doc_js_name,
335 NATIVESPEC=self._backend.NativeSpec()) 348 NATIVESPEC=self._backend.NativeSpec())
336 self._backend.StartInterface(self._implementation_members_emitter) 349 self._backend.StartInterface(self._implementation_members_emitter)
337 350
338 for constructor_info in constructors: 351 for constructor_info in constructors:
339 constructor_info.GenerateFactoryInvocation( 352 constructor_info.GenerateFactoryInvocation(
340 self._DartType, self._members_emitter, factory_provider) 353 self._DartType, self._members_emitter, factory_provider)
341 354
342 element_type = None 355 self._backend.AddConstructors(constructors, factory_provider,
356 self._interface_type_info.implementation_name(),
357 base_class)
358
359 typed_array_type = None
343 for interface in self._database.Hierarchy(self._interface): 360 for interface in self._database.Hierarchy(self._interface):
344 type_info = self._type_registry.TypeInfo(interface.id) 361 type_info = self._type_registry.TypeInfo(interface.id)
345 if type_info.is_typed_array(): 362 if type_info.is_typed_array():
346 element_type = type_info.list_item_type() 363 typed_array_type = type_info.list_item_type()
347 break 364 break
348 if element_type: 365 if typed_array_type:
349 self._members_emitter.Emit( 366 self._members_emitter.Emit(
350 '\n' 367 '\n'
351 ' factory $CTOR(int length) =>\n' 368 ' factory $CTOR(int length) =>\n'
352 ' $FACTORY.create$(CTOR)(length);\n' 369 ' $FACTORY.create$(CTOR)(length);\n'
353 '\n' 370 '\n'
354 ' factory $CTOR.fromList(List<$TYPE> list) =>\n' 371 ' factory $CTOR.fromList(List<$TYPE> list) =>\n'
355 ' $FACTORY.create$(CTOR)_fromList(list);\n' 372 ' $FACTORY.create$(CTOR)_fromList(list);\n'
356 '\n' 373 '\n'
357 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l ength]) => \n' 374 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l ength]) => \n'
358 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n' , 375 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n' ,
359 CTOR=self._interface.id, 376 CTOR=self._interface.id,
360 TYPE=self._DartType(element_type), 377 TYPE=self._DartType(typed_array_type),
361 FACTORY=factory_provider) 378 FACTORY=factory_provider)
362 379
363 events_interface = self._event_generator.ProcessInterface( 380 events_interface = self._event_generator.ProcessInterface(
364 self._interface, interface_name, 381 self._interface, interface_name,
365 self._backend.CustomJSMembers(), 382 self._backend.CustomJSMembers(),
366 interface_emitter, implementation_emitter) 383 interface_emitter, implementation_emitter)
367 if events_interface: 384 if events_interface:
368 self._EmitEventGetter(events_interface, '_%sImpl' % events_interface) 385 self._EmitEventGetter(events_interface, events_interface)
369 386
370 old_backend = self._backend 387 old_backend = self._backend
371 if not self._backend.ImplementsMergedMembers(): 388 if not self._backend.ImplementsMergedMembers():
372 self._backend = HtmlGeneratorDummyBackend() 389 self._backend = HtmlGeneratorDummyBackend()
373 merged_interface = self._interface_type_info.merged_interface() 390 merged_interface = self._interface_type_info.merged_interface()
374 if merged_interface: 391 if merged_interface:
375 self.AddMembers(self._database.GetInterface(merged_interface)) 392 self.AddMembers(self._database.GetInterface(merged_interface))
376 self._backend = old_backend 393 self._backend = old_backend
377 394
378 self.AddMembers(self._interface) 395 self.AddMembers(self._interface)
396 if merged_interface and not self._backend.ImplementsMergedMembers():
397 self.AddMembers(self._database.GetInterface(merged_interface), True)
398
379 self.AddSecondaryMembers(self._interface) 399 self.AddSecondaryMembers(self._interface)
380 self._backend.FinishInterface() 400 self._backend.FinishInterface()
381 401
382 def AddMembers(self, interface): 402 def AddMembers(self, interface, declare_only=False):
383 for const in sorted(interface.constants, ConstantOutputOrder): 403 for const in sorted(interface.constants, ConstantOutputOrder):
384 self.AddConstant(const) 404 self.AddConstant(const)
385 405
386 for attr in sorted(interface.attributes, ConstantOutputOrder): 406 for attr in sorted(interface.attributes, ConstantOutputOrder):
387 if attr.type.id != 'EventListener': 407 if attr.type.id != 'EventListener':
388 self.AddAttribute(attr) 408 self.AddAttribute(attr, False, declare_only)
389 409
390 # The implementation should define an indexer if the interface directly 410 # The implementation should define an indexer if the interface directly
391 # extends List. 411 # extends List.
392 element_type = None 412 element_type = None
393 requires_indexer = False 413 requires_indexer = False
394 if self._interface_type_info.list_item_type(): 414 if self._interface_type_info.list_item_type():
395 self.AddIndexer(self._interface_type_info.list_item_type()) 415 self.AddIndexer(self._interface_type_info.list_item_type())
396 else: 416 else:
397 for parent in self._database.Hierarchy(self._interface): 417 for parent in self._database.Hierarchy(self._interface):
398 if parent == self._interface: 418 if parent == self._interface:
399 continue 419 continue
400 parent_type_info = self._type_registry.TypeInfo(parent.id) 420 parent_type_info = self._type_registry.TypeInfo(parent.id)
401 if parent_type_info.list_item_type(): 421 if parent_type_info.list_item_type():
402 self.AmendIndexer(parent_type_info.list_item_type()) 422 self.AmendIndexer(parent_type_info.list_item_type())
403 break 423 break
404 424
405 # Group overloaded operations by id 425 # Group overloaded operations by id
406 operationsById = {} 426 operationsById = {}
407 for operation in interface.operations: 427 for operation in interface.operations:
408 if operation.id not in operationsById: 428 if operation.id not in operationsById:
409 operationsById[operation.id] = [] 429 operationsById[operation.id] = []
410 operationsById[operation.id].append(operation) 430 operationsById[operation.id].append(operation)
411 431
412 # Generate operations 432 # Generate operations
413 for id in sorted(operationsById.keys()): 433 for id in sorted(operationsById.keys()):
414 operations = operationsById[id] 434 operations = operationsById[id]
415 info = AnalyzeOperation(interface, operations) 435 info = AnalyzeOperation(interface, operations)
416 self.AddOperation(info) 436 self.AddOperation(info, False, declare_only)
417 437
418 def AddSecondaryMembers(self, interface): 438 def AddSecondaryMembers(self, interface):
419 # With multiple inheritance, attributes and operations of non-first 439 # With multiple inheritance, attributes and operations of non-first
420 # interfaces need to be added. Sometimes the attribute or operation is 440 # interfaces need to be added. Sometimes the attribute or operation is
421 # defined in the current interface as well as a parent. In that case we 441 # defined in the current interface as well as a parent. In that case we
422 # avoid making a duplicate definition and pray that the signatures match. 442 # avoid making a duplicate definition and pray that the signatures match.
423 secondary_parents = self._TransitiveSecondaryParents(interface) 443 secondary_parents = self._TransitiveSecondaryParents(interface)
424 for parent_interface in sorted(secondary_parents): 444 for parent_interface in sorted(secondary_parents):
425 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter face) 445 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter face)
426 continue 446 continue
(...skipping 14 matching lines...) Expand all
441 operations = operationsById[id] 461 operations = operationsById[id]
442 info = AnalyzeOperation(interface, operations) 462 info = AnalyzeOperation(interface, operations)
443 self.AddSecondaryOperation(parent_interface, info) 463 self.AddSecondaryOperation(parent_interface, info)
444 464
445 def AddIndexer(self, element_type): 465 def AddIndexer(self, element_type):
446 self._backend.AddIndexer(element_type) 466 self._backend.AddIndexer(element_type)
447 467
448 def AmendIndexer(self, element_type): 468 def AmendIndexer(self, element_type):
449 self._backend.AmendIndexer(element_type) 469 self._backend.AmendIndexer(element_type)
450 470
451 def AddAttribute(self, attribute, is_secondary=False): 471 def AddAttribute(self, attribute, is_secondary=False, declare_only=False):
452 dom_name = DartDomNameOfAttribute(attribute) 472 dom_name = DartDomNameOfAttribute(attribute)
453 html_name = self._renamer.RenameMember( 473 html_name = self._renamer.RenameMember(
454 self._interface.id, attribute, dom_name, 'get:') 474 self._interface.id, attribute, dom_name, 'get:')
455 if not html_name or self._IsPrivate(html_name): 475 if not html_name or self._IsPrivate(html_name):
456 return 476 return
457 477
458 478
459 html_setter_name = self._renamer.RenameMember( 479 html_setter_name = self._renamer.RenameMember(
460 self._interface.id, attribute, dom_name, 'set:') 480 self._interface.id, attribute, dom_name, 'set:')
461 read_only = (attribute.is_read_only or 'Replaceable' in attribute.ext_attrs 481 read_only = (attribute.is_read_only or 'Replaceable' in attribute.ext_attrs
462 or not html_setter_name) 482 or not html_setter_name)
463 483
464 # We don't yet handle inconsistent renames of the getter and setter yet. 484 # We don't yet handle inconsistent renames of the getter and setter yet.
465 assert(not html_setter_name or html_name == html_setter_name) 485 assert(not html_setter_name or html_name == html_setter_name)
466 486
467 if not is_secondary: 487 if not is_secondary:
468 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */', 488 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
469 DOMINTERFACE=attribute.doc_js_interface_name, 489 DOMINTERFACE=attribute.doc_js_interface_name,
470 DOMNAME=dom_name) 490 DOMNAME=dom_name)
471 if read_only: 491 if read_only:
472 template = '\n $TYPE get $NAME;\n' 492 template = '\n $TYPE get $NAME;\n'
473 else: 493 else:
474 template = '\n $TYPE $NAME;\n' 494 template = '\n $TYPE $NAME;\n'
475 495
476 self._members_emitter.Emit(template, 496 self._members_emitter.Emit(template,
477 NAME=html_name, 497 NAME=html_name,
478 TYPE=SecureOutputType(self, attribute.type.id)) 498 TYPE=SecureOutputType(self, attribute.type.id))
479 499
480 self._backend.AddAttribute(attribute, html_name, read_only) 500 if declare_only:
501 self._backend.DeclareAttribute(attribute,
502 SecureOutputType(self, attribute.type.id), html_name, read_only)
503 else:
504 self._backend.AddAttribute(attribute, html_name, read_only)
481 505
482 def AddSecondaryAttribute(self, interface, attribute): 506 def AddSecondaryAttribute(self, interface, attribute):
483 self._backend.SecondaryContext(interface) 507 self._backend.SecondaryContext(interface)
484 self.AddAttribute(attribute, True) 508 self.AddAttribute(attribute, True)
485 509
486 def AddOperation(self, info, skip_declaration=False): 510 def AddOperation(self, info, skip_declaration=False, declare_only=False):
487 """ 511 """
488 Arguments: 512 Arguments:
489 operations - contains the overloads, one or more operations with the same 513 operations - contains the overloads, one or more operations with the same
490 name. 514 name.
491 """ 515 """
492 # FIXME: When we pass in operations[0] below, we're assuming all 516 # FIXME: When we pass in operations[0] below, we're assuming all
493 # overloaded operations have the same security attributes. This 517 # overloaded operations have the same security attributes. This
494 # is currently true, but we should consider filtering earlier or 518 # is currently true, but we should consider filtering earlier or
495 # merging the relevant data into info itself. 519 # merging the relevant data into info itself.
496 html_name = self._renamer.RenameMember(self._interface.id, 520 html_name = self._renamer.RenameMember(self._interface.id,
(...skipping 17 matching lines...) Expand all
514 ' static final $NAME = $IMPL_CLASS_NAME.$NAME;\n', 538 ' static final $NAME = $IMPL_CLASS_NAME.$NAME;\n',
515 IMPL_CLASS_NAME=self._interface_type_info.implementation_name(), 539 IMPL_CLASS_NAME=self._interface_type_info.implementation_name(),
516 NAME=html_name) 540 NAME=html_name)
517 else: 541 else:
518 self._members_emitter.Emit( 542 self._members_emitter.Emit(
519 '\n' 543 '\n'
520 ' $TYPE $NAME($PARAMS);\n', 544 ' $TYPE $NAME($PARAMS);\n',
521 TYPE=SecureOutputType(self, info.type_name), 545 TYPE=SecureOutputType(self, info.type_name),
522 NAME=html_name, 546 NAME=html_name,
523 PARAMS=info.ParametersDeclaration(self._DartType)) 547 PARAMS=info.ParametersDeclaration(self._DartType))
524 self._backend.AddOperation(info, html_name) 548 if declare_only:
549 self._backend.DeclareOperation(info,
550 SecureOutputType(self, info.type_name), html_name)
551 else:
552 self._backend.AddOperation(info, html_name)
525 553
526 def AddSecondaryOperation(self, interface, info): 554 def AddSecondaryOperation(self, interface, info):
527 self._backend.SecondaryContext(interface) 555 self._backend.SecondaryContext(interface)
528 self.AddOperation(info, True) 556 self.AddOperation(info)
529 557
530 def AddConstant(self, constant): 558 def AddConstant(self, constant):
531 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) 559 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
532 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', 560 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
533 NAME=constant.id, 561 NAME=constant.id,
534 TYPE=type, 562 TYPE=type,
535 VALUE=constant.value) 563 VALUE=constant.value)
536 564
565 self._backend.AddConstant(constant)
566
537 def _ImplementationEmitter(self): 567 def _ImplementationEmitter(self):
538 if IsPureInterface(self._interface.id):
539 return emitter.Emitter()
540 basename = self._interface_type_info.implementation_name() 568 basename = self._interface_type_info.implementation_name()
541 if (self._interface_type_info.merged_into() and 569 if (self._interface_type_info.merged_into() and
542 self._backend.ImplementsMergedMembers()): 570 self._backend.ImplementsMergedMembers()):
543 # Merged members are implemented in target interface implementation. 571 # Merged members are implemented in target interface implementation.
544 return emitter.Emitter() 572 return emitter.Emitter()
545 return self._library_emitter.FileEmitter(basename.lstrip('_')) 573 return self._library_emitter.FileEmitter(basename)
546 574
547 def _EmitEventGetter(self, events_interface, events_class): 575 def _EmitEventGetter(self, events_interface, events_class):
548 self._members_emitter.Emit( 576 self._members_emitter.Emit(
549 '\n /**' 577 '\n /**'
550 '\n * @domName EventTarget.addEventListener, ' 578 '\n * @domName EventTarget.addEventListener, '
551 'EventTarget.removeEventListener, EventTarget.dispatchEvent' 579 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
552 '\n */' 580 '\n */'
553 '\n $TYPE get on;\n', 581 '\n $TYPE get on;\n',
554 TYPE=events_interface) 582 TYPE=events_interface)
555 583
556 self._implementation_members_emitter.Emit( 584 self._implementation_members_emitter.Emit(
585 '\n /**'
586 '\n * @domName EventTarget.addEventListener, '
587 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
588 '\n */'
557 '\n $TYPE get on =>\n new $TYPE(this);\n', 589 '\n $TYPE get on =>\n new $TYPE(this);\n',
558 TYPE=events_class) 590 TYPE=events_class)
559 591
560 def _TransitiveSecondaryParents(self, interface): 592 def _TransitiveSecondaryParents(self, interface):
561 """Returns a list of all non-primary parents. 593 """Returns a list of all non-primary parents.
562 594
563 The list contains the interface objects for interfaces defined in the 595 The list contains the interface objects for interfaces defined in the
564 database, and the name for undefined interfaces. 596 database, and the name for undefined interfaces.
565 """ 597 """
566 def walk(parents): 598 def walk(parents):
(...skipping 30 matching lines...) Expand all
597 class HtmlGeneratorDummyBackend(object): 629 class HtmlGeneratorDummyBackend(object):
598 def AddAttribute(self, attribute, html_name, read_only): 630 def AddAttribute(self, attribute, html_name, read_only):
599 pass 631 pass
600 632
601 def AddOperation(self, info, html_name): 633 def AddOperation(self, info, html_name):
602 pass 634 pass
603 635
604 636
605 # ------------------------------------------------------------------------------ 637 # ------------------------------------------------------------------------------
606 638
607 class Dart2JSBackend(object): 639 class Dart2JSBackend(HtmlDartGenerator):
608 """Generates a dart2js class for the dart:html library from a DOM IDL 640 """Generates a dart2js class for the dart:html library from a DOM IDL
609 interface. 641 interface.
610 """ 642 """
611 643
612 def __init__(self, interface, options): 644 def __init__(self, interface, options):
613 self._interface = interface 645 super(Dart2JSBackend, self).__init__(interface, options)
646
614 self._database = options.database 647 self._database = options.database
615 self._template_loader = options.templates 648 self._template_loader = options.templates
616 self._type_registry = options.type_registry 649 self._type_registry = options.type_registry
650 self._renamer = options.renamer
617 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) 651 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
618 self._current_secondary_parent = None 652 self._current_secondary_parent = None
619 653
620 def ImplementsMergedMembers(self): 654 def ImplementsMergedMembers(self):
621 return True 655 return True
622 656
623 def GenerateCallback(self, info): 657 def GenerateCallback(self, info):
624 pass 658 pass
625 659
626 def RootClassName(self): 660 def RootClassName(self):
627 return None 661 return None
628 662
629 def AdditionalImplementedInterfaces(self): 663 def AdditionalImplementedInterfaces(self):
630 # TODO: Include all implemented interfaces, including other Lists. 664 implements = super(Dart2JSBackend, self).AdditionalImplementedInterfaces()
631 implements = []
632 if self._interface_type_info.is_typed_array():
633 element_type = self._interface_type_info.list_item_type()
634 implements.append('List<%s>' % self._DartType(element_type))
635 if self._interface_type_info.list_item_type(): 665 if self._interface_type_info.list_item_type():
636 implements.append('JavaScriptIndexingBehavior') 666 implements.append('JavaScriptIndexingBehavior')
637 return implements 667 return implements
638 668
639 def NativeSpec(self): 669 def NativeSpec(self):
640 native_spec = MakeNativeSpec(self._interface.javascript_binding_name) 670 native_spec = MakeNativeSpec(self._interface.javascript_binding_name)
641 return ' native "%s"' % native_spec 671 return ' native "%s"' % native_spec
642 672
643 def ImplementationTemplate(self): 673 def ImplementationTemplate(self):
674 if IsPureInterface(self._interface.id):
675 return self._template_loader.Load('pure_interface.darttemplate')
676
644 template_file = ('impl_%s.darttemplate' % 677 template_file = ('impl_%s.darttemplate' %
645 self._interface_type_info.interface_name()) 678 self._interface_type_info.interface_name())
646 return (self._template_loader.TryLoad(template_file) or 679 return (self._template_loader.TryLoad(template_file) or
647 self._template_loader.Load('dart2js_impl.darttemplate')) 680 self._template_loader.Load('dart2js_impl.darttemplate'))
648 681
649 def StartInterface(self, emitter): 682 def StartInterface(self, emitter):
650 self._members_emitter = emitter 683 self._members_emitter = emitter
651 684
652 def FinishInterface(self): 685 def FinishInterface(self):
653 pass 686 pass
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 has_contains = any(op.id == 'contains' for op in self._interface.operation s) 759 has_contains = any(op.id == 'contains' for op in self._interface.operation s)
727 template = self._template_loader.Load( 760 template = self._template_loader.Load(
728 template_file, 761 template_file,
729 {'DEFINE_CONTAINS': not has_contains}) 762 {'DEFINE_CONTAINS': not has_contains})
730 self._members_emitter.Emit(template, E=self._DartType(element_type)) 763 self._members_emitter.Emit(template, E=self._DartType(element_type))
731 764
732 def AddAttribute(self, attribute, html_name, read_only): 765 def AddAttribute(self, attribute, html_name, read_only):
733 if self._HasCustomImplementation(attribute.id): 766 if self._HasCustomImplementation(attribute.id):
734 return 767 return
735 768
769 if IsPureInterface(self._interface.id):
770 self._AddInterfaceAttribute(attribute)
771 return
772
736 if attribute.id != html_name: 773 if attribute.id != html_name:
737 self._AddAttributeUsingProperties(attribute, html_name, read_only) 774 self._AddAttributeUsingProperties(attribute, html_name, read_only)
738 return 775 return
739 776
740 # If the attribute is shadowing, we can't generate a shadowing 777 # If the attribute is shadowing, we can't generate a shadowing
741 # field (Issue 1633). 778 # field (Issue 1633).
742 # TODO(sra): _FindShadowedAttribute does not take into account the html 779 # TODO(sra): _FindShadowedAttribute does not take into account the html
743 # renaming. we should be looking for another attribute that has the same 780 # renaming. we should be looking for another attribute that has the same
744 # html_name. Two attributes with the same IDL name might not match if one 781 # html_name. Two attributes with the same IDL name might not match if one
745 # is renamed. 782 # is renamed.
(...skipping 18 matching lines...) Expand all
764 801
765 # If the type has a conversion we need a getter or setter to contain the 802 # If the type has a conversion we need a getter or setter to contain the
766 # conversion code. 803 # conversion code.
767 if (self._OutputConversion(attribute.type.id, attribute.id) or 804 if (self._OutputConversion(attribute.type.id, attribute.id) or
768 self._InputConversion(attribute.type.id, attribute.id)): 805 self._InputConversion(attribute.type.id, attribute.id)):
769 self._AddAttributeUsingProperties(attribute, html_name, read_only) 806 self._AddAttributeUsingProperties(attribute, html_name, read_only)
770 return 807 return
771 808
772 output_type = self._NarrowOutputType(attribute.type.id) 809 output_type = self._NarrowOutputType(attribute.type.id)
773 input_type = self._NarrowInputType(attribute.type.id) 810 input_type = self._NarrowInputType(attribute.type.id)
811 self.EmitAttributeDocumentation(attribute)
774 if not read_only: 812 if not read_only:
775 self._members_emitter.Emit( 813 self._members_emitter.Emit(
776 '\n $TYPE $NAME;' 814 '\n $TYPE $NAME;'
777 '\n', 815 '\n',
778 NAME=DartDomNameOfAttribute(attribute), 816 NAME=DartDomNameOfAttribute(attribute),
779 TYPE=output_type) 817 TYPE=output_type)
780 else: 818 else:
781 self._members_emitter.Emit( 819 self._members_emitter.Emit(
782 '\n final $TYPE $NAME;' 820 '\n final $TYPE $NAME;'
783 '\n', 821 '\n',
784 NAME=DartDomNameOfAttribute(attribute), 822 NAME=DartDomNameOfAttribute(attribute),
785 TYPE=output_type) 823 TYPE=output_type)
786 824
787 def _AddAttributeUsingProperties(self, attribute, html_name, read_only): 825 def _AddAttributeUsingProperties(self, attribute, html_name, read_only):
788 self._AddRenamingGetter(attribute, html_name) 826 self._AddRenamingGetter(attribute, html_name)
789 if not read_only: 827 if not read_only:
790 self._AddRenamingSetter(attribute, html_name) 828 self._AddRenamingSetter(attribute, html_name)
791 829
830 def _AddInterfaceAttribute(self, attribute):
831 self._members_emitter.Emit(
832 '\n $TYPE $NAME;'
833 '\n',
834 NAME=DartDomNameOfAttribute(attribute),
835 TYPE=self._NarrowOutputType(attribute.type.id))
836
792 def _AddRenamingGetter(self, attr, html_name): 837 def _AddRenamingGetter(self, attr, html_name):
838 self.EmitAttributeDocumentation(attr)
839
793 conversion = self._OutputConversion(attr.type.id, attr.id) 840 conversion = self._OutputConversion(attr.type.id, attr.id)
794 if conversion: 841 if conversion:
795 return self._AddConvertingGetter(attr, html_name, conversion) 842 return self._AddConvertingGetter(attr, html_name, conversion)
796 return_type = self._NarrowOutputType(attr.type.id) 843 return_type = self._NarrowOutputType(attr.type.id)
797 self._members_emitter.Emit( 844 self._members_emitter.Emit(
798 # TODO(sra): Use metadata to provide native name. 845 # TODO(sra): Use metadata to provide native name.
799 '\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);' 846 '\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);'
800 '\n', 847 '\n',
801 HTML_NAME=html_name, 848 HTML_NAME=html_name,
802 NAME=attr.id, 849 NAME=attr.id,
803 TYPE=return_type) 850 TYPE=return_type)
804 851
805 def _AddRenamingSetter(self, attr, html_name): 852 def _AddRenamingSetter(self, attr, html_name):
853 self.EmitAttributeDocumentation(attr)
854
806 conversion = self._InputConversion(attr.type.id, attr.id) 855 conversion = self._InputConversion(attr.type.id, attr.id)
807 if conversion: 856 if conversion:
808 return self._AddConvertingSetter(attr, html_name, conversion) 857 return self._AddConvertingSetter(attr, html_name, conversion)
809 self._members_emitter.Emit( 858 self._members_emitter.Emit(
810 # TODO(sra): Use metadata to provide native name. 859 # TODO(sra): Use metadata to provide native name.
811 '\n void set $HTML_NAME($TYPE value) {' 860 '\n void set $HTML_NAME($TYPE value) {'
812 '\n JS("void", "#.$NAME = #", this, value);' 861 '\n JS("void", "#.$NAME = #", this, value);'
813 '\n }' 862 '\n }'
814 '\n', 863 '\n',
815 HTML_NAME=html_name, 864 HTML_NAME=html_name,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 pass 898 pass
850 899
851 def AddOperation(self, info, html_name): 900 def AddOperation(self, info, html_name):
852 """ 901 """
853 Arguments: 902 Arguments:
854 info: An OperationInfo object. 903 info: An OperationInfo object.
855 """ 904 """
856 if self._HasCustomImplementation(info.name): 905 if self._HasCustomImplementation(info.name):
857 return 906 return
858 907
859 # Any conversions needed? 908 self.EmitOperationDocumentation(info)
860 if any(self._OperationRequiresConversions(op) for op in info.overloads): 909
910 if IsPureInterface(self._interface.id):
911 self._AddInterfaceOperation(info, html_name)
912 elif any(self._OperationRequiresConversions(op) for op in info.overloads):
913 # Any conversions needed?
861 self._AddOperationWithConversions(info, html_name) 914 self._AddOperationWithConversions(info, html_name)
862 else: 915 else:
863 self._AddDirectNativeOperation(info, html_name) 916 self._AddDirectNativeOperation(info, html_name)
864 917
865 def _AddDirectNativeOperation(self, info, html_name): 918 def _AddDirectNativeOperation(self, info, html_name):
866 # Do we need a native body? 919 # Do we need a native body?
867 if html_name != info.declared_name: 920 if html_name != info.declared_name:
868 return_type = self._NarrowOutputType(info.type_name) 921 return_type = self._NarrowOutputType(info.type_name)
869 922
870 operation_emitter = self._members_emitter.Emit('$!SCOPE', 923 operation_emitter = self._members_emitter.Emit('$!SCOPE',
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 else: 1072 else:
1020 operation = operations[0] 1073 operation = operations[0]
1021 argument_count = len(operation.arguments) 1074 argument_count = len(operation.arguments)
1022 for position, argument in list(enumerate(operation.arguments))[::-1]: 1075 for position, argument in list(enumerate(operation.arguments))[::-1]:
1023 if self._IsOptional(operation, argument): 1076 if self._IsOptional(operation, argument):
1024 check = '?%s' % parameter_names[position] 1077 check = '?%s' % parameter_names[position]
1025 GenerateCall(operation, position + 1, [check]) 1078 GenerateCall(operation, position + 1, [check])
1026 argument_count = position 1079 argument_count = position
1027 GenerateCall(operation, argument_count, []) 1080 GenerateCall(operation, argument_count, [])
1028 1081
1082 def _AddInterfaceOperation(self, info, html_name):
1083 self._members_emitter.Emit(
1084 '\n'
1085 ' $TYPE $NAME($PARAMS);\n',
1086 TYPE=self._NarrowOutputType(info.type_name),
1087 NAME=info.name,
1088 PARAMS=info.ParametersDeclaration(self._NarrowInputType))
1089
1090 def AddConstant(self, constant):
1091 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
1092 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
1093 NAME=constant.id,
1094 TYPE=type,
1095 VALUE=constant.value)
1029 1096
1030 def _IsOptional(self, operation, argument): 1097 def _IsOptional(self, operation, argument):
1031 return IsOptional(argument) 1098 return IsOptional(argument)
1032 1099
1033 1100
1034 def _OperationRequiresConversions(self, operation): 1101 def _OperationRequiresConversions(self, operation):
1035 return (self._OperationRequiresOutputConversion(operation) or 1102 return (self._OperationRequiresOutputConversion(operation) or
1036 self._OperationRequiresInputConversions(operation)) 1103 self._OperationRequiresInputConversions(operation))
1037 1104
1038 def _OperationRequiresOutputConversion(self, operation): 1105 def _OperationRequiresOutputConversion(self, operation):
(...skipping 17 matching lines...) Expand all
1056 def CustomJSMembers(self): 1123 def CustomJSMembers(self):
1057 return _js_custom_members 1124 return _js_custom_members
1058 1125
1059 def _NarrowToImplementationType(self, type_name): 1126 def _NarrowToImplementationType(self, type_name):
1060 return self._type_registry.TypeInfo(type_name).narrow_dart_type() 1127 return self._type_registry.TypeInfo(type_name).narrow_dart_type()
1061 1128
1062 def _NarrowInputType(self, type_name): 1129 def _NarrowInputType(self, type_name):
1063 return self._NarrowToImplementationType(type_name) 1130 return self._NarrowToImplementationType(type_name)
1064 1131
1065 def _NarrowOutputType(self, type_name): 1132 def _NarrowOutputType(self, type_name):
1066 secure_name = SecureOutputType(self, type_name, True) 1133 return SecureOutputType(self, type_name)
1067 return self._NarrowToImplementationType(secure_name)
1068 1134
1069 def _FindShadowedAttribute(self, attr): 1135 def _FindShadowedAttribute(self, attr):
1070 """Returns (attribute, superinterface) or (None, None).""" 1136 """Returns (attribute, superinterface) or (None, None)."""
1071 def FindInParent(interface): 1137 def FindInParent(interface):
1072 """Returns matching attribute in parent, or None.""" 1138 """Returns matching attribute in parent, or None."""
1073 if interface.parents: 1139 if interface.parents:
1074 parent = interface.parents[0] 1140 parent = interface.parents[0]
1075 if IsDartCollectionType(parent.type.id): 1141 if IsDartCollectionType(parent.type.id):
1076 return (None, None) 1142 return (None, None)
1077 if IsPureInterface(parent.type.id): 1143 if IsPureInterface(parent.type.id):
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 1196
1131 library_emitter = self._multiemitter.FileEmitter(library_file_path) 1197 library_emitter = self._multiemitter.FileEmitter(library_file_path)
1132 library_file_dir = os.path.dirname(library_file_path) 1198 library_file_dir = os.path.dirname(library_file_path)
1133 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) 1199 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir)
1134 imports_emitter = library_emitter.Emit( 1200 imports_emitter = library_emitter.Emit(
1135 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) 1201 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir))
1136 for path in sorted(self._path_to_emitter.keys()): 1202 for path in sorted(self._path_to_emitter.keys()):
1137 relpath = os.path.relpath(path, library_file_dir) 1203 relpath = os.path.relpath(path, library_file_dir)
1138 imports_emitter.Emit( 1204 imports_emitter.Emit(
1139 "part '$PATH';\n", PATH=massage_path(relpath)) 1205 "part '$PATH';\n", PATH=massage_path(relpath))
OLDNEW
« no previous file with comments | « sdk/lib/html/scripts/htmleventgenerator.py ('k') | sdk/lib/html/scripts/systemnative.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698