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

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

Issue 11363130: Cleaning up dart:html generation after interface/implementation merge. Removing most of the interfa… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporating review feedback, cleaning up comments 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
(...skipping 29 matching lines...) Expand all
40 'Url.revokeObjectURL', 40 'Url.revokeObjectURL',
41 'WheelEvent.wheelDeltaX', 41 'WheelEvent.wheelDeltaX',
42 'WheelEvent.wheelDeltaY', 42 'WheelEvent.wheelDeltaY',
43 ]) 43 ])
44 44
45 45
46 # Classes that offer only static methods, and therefore we should suppress 46 # Classes that offer only static methods, and therefore we should suppress
47 # constructor creation. 47 # constructor creation.
48 _static_classes = set(['Url']) 48 _static_classes = set(['Url'])
49 49
50 # Types that are accessible cross-frame in a limited fashion.
51 # In these cases, the base type (e.g., Window) provides restricted access
52 # while the subtype (e.g., LocalWindow) provides full access to the
53 # corresponding objects if there are from the same frame.
54 _secure_base_types = {
55 'LocalWindow': 'Window',
56 'LocalLocation': 'Location',
57 'LocalHistory': 'History',
58 }
59
60 def SecureOutputType(generator, type_name, is_dart_type=False):
61 if is_dart_type:
62 dart_name = type_name
63 else:
64 dart_name = generator._DartType(type_name)
65 # We only need to secure Window. Only local History and Location are returned
66 # in generated code.
67 if dart_name == 'LocalWindow':
68 return _secure_base_types[dart_name]
69 return dart_name
70
71 # Information for generating element constructors. 50 # Information for generating element constructors.
72 # 51 #
73 # TODO(sra): maybe remove all the argument complexity and use cascades. 52 # TODO(sra): maybe remove all the argument complexity and use cascades.
74 # 53 #
75 # var c = new CanvasElement(width: 100, height: 70); 54 # var c = new CanvasElement(width: 100, height: 70);
76 # var c = new CanvasElement()..width = 100..height = 70; 55 # var c = new CanvasElement()..width = 100..height = 70;
77 # 56 #
78 class ElementConstructorInfo(object): 57 class ElementConstructorInfo(object):
79 def __init__(self, name=None, tag=None, 58 def __init__(self, name=None, tag=None,
80 params=[], opt_params=[], 59 params=[], opt_params=[],
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 185
207 class HtmlDartInterfaceGenerator(object): 186 class HtmlDartInterfaceGenerator(object):
208 """Generates dart interface and implementation for the DOM IDL interface.""" 187 """Generates dart interface and implementation for the DOM IDL interface."""
209 188
210 def __init__(self, options, library_emitter, event_generator, interface, 189 def __init__(self, options, library_emitter, event_generator, interface,
211 backend): 190 backend):
212 self._renamer = options.renamer 191 self._renamer = options.renamer
213 self._database = options.database 192 self._database = options.database
214 self._template_loader = options.templates 193 self._template_loader = options.templates
215 self._type_registry = options.type_registry 194 self._type_registry = options.type_registry
195 self._options = options
216 self._library_emitter = library_emitter 196 self._library_emitter = library_emitter
217 self._event_generator = event_generator 197 self._event_generator = event_generator
218 self._interface = interface 198 self._interface = interface
219 self._backend = backend 199 self._backend = backend
220 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id) 200 self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
221 201
222 def Generate(self): 202 def Generate(self):
223 if 'Callback' in self._interface.ext_attrs: 203 if 'Callback' in self._interface.ext_attrs:
224 self.GenerateCallback() 204 self.GenerateCallback()
225 else: 205 else:
226 self.GenerateInterface() 206 self.GenerateInterface()
227 207
228 def GenerateCallback(self): 208 def GenerateCallback(self):
229 """Generates a typedef for the callback interface.""" 209 """Generates a typedef for the callback interface."""
230 handlers = [operation for operation in self._interface.operations 210 handlers = [operation for operation in self._interface.operations
231 if operation.id == 'handleEvent'] 211 if operation.id == 'handleEvent']
232 info = AnalyzeOperation(self._interface, handlers) 212 info = AnalyzeOperation(self._interface, handlers)
233 code = self._library_emitter.FileEmitter(self._interface.id) 213 code = self._library_emitter.FileEmitter(self._interface.id)
234 code.Emit(self._template_loader.Load('callback.darttemplate')) 214 code.Emit(self._template_loader.Load('callback.darttemplate'))
235 code.Emit('typedef void $NAME($PARAMS);\n', 215 code.Emit('typedef void $NAME($PARAMS);\n',
236 NAME=self._interface.id, 216 NAME=self._interface.id,
237 PARAMS=info.ParametersDeclaration(self._DartType)) 217 PARAMS=info.ParametersDeclaration(self._DartType))
238 self._backend.GenerateCallback(info) 218 self._backend.GenerateCallback(info)
239 219
240 def GenerateInterface(self): 220 def GenerateInterface(self):
241 interface_name = self._interface_type_info.interface_name() 221 interface_name = self._interface_type_info.interface_name()
242 222
243 # TODO: this is just tossing the interface, need to skip it completely.
244 interface_emitter = emitter.Emitter()
245
246 template_file = 'interface_%s.darttemplate' % interface_name
247 interface_template = (self._template_loader.TryLoad(template_file) or
248 self._template_loader.Load('interface.darttemplate'))
249
250 implements = []
251 for parent in self._interface.parents:
252 parent_type_info = self._type_registry.TypeInfo(parent.type.id)
253 implements.append(parent_type_info.interface_name())
254
255 if self._interface_type_info.list_item_type():
256 item_type_info = self._type_registry.TypeInfo(
257 self._interface_type_info.list_item_type())
258 implements.append('List<%s>' % item_type_info.dart_type())
259
260 if interface_name in _secure_base_types:
261 implements.append(_secure_base_types[interface_name])
262
263 comment = ' extends'
264 implements_str = ''
265 if implements:
266 implements_str += ' implements ' + ', '.join(implements)
267 comment = ','
268
269 factory_provider = None 223 factory_provider = None
270 if interface_name in interface_factories: 224 if interface_name in interface_factories:
271 factory_provider = interface_factories[interface_name] 225 factory_provider = interface_factories[interface_name]
272 226
273 constructors = [] 227 constructors = []
274 if interface_name in _static_classes: 228 if interface_name in _static_classes:
275 constructor_info = None 229 constructor_info = None
276 else: 230 else:
277 constructor_info = AnalyzeConstructor(self._interface) 231 constructor_info = AnalyzeConstructor(self._interface)
278 if constructor_info: 232 if constructor_info:
(...skipping 15 matching lines...) Expand all
294 self._interface_type_info.implementation_name(), 248 self._interface_type_info.implementation_name(),
295 self._DartType) 249 self._DartType)
296 250
297 for info in infos: 251 for info in infos:
298 constructors.append(info.ConstructorInfo(self._interface.id)) 252 constructors.append(info.ConstructorInfo(self._interface.id))
299 if factory_provider: 253 if factory_provider:
300 assert factory_provider == info.factory_provider_name 254 assert factory_provider == info.factory_provider_name
301 else: 255 else:
302 factory_provider = info.factory_provider_name 256 factory_provider = info.factory_provider_name
303 257
304 # TODO(vsm): Add appropriate package / namespace syntax.
305 (self._type_comment_emitter,
306 self._members_emitter,
307 self._top_level_emitter) = interface_emitter.Emit(
308 interface_template + '$!TOP_LEVEL',
309 ID='_I%s' % interface_name,
310 EXTENDS=implements_str)
311
312 implementation_emitter = self._ImplementationEmitter() 258 implementation_emitter = self._ImplementationEmitter()
313 259
314 base_type_info = None 260 base_type_info = None
315 if self._interface.parents: 261 if self._interface.parents:
316 supertype = self._interface.parents[0].type.id 262 supertype = self._interface.parents[0].type.id
317 if not IsDartCollectionType(supertype) and not IsPureInterface(supertype): 263 if not IsDartCollectionType(supertype) and not IsPureInterface(supertype):
318 base_type_info = self._type_registry.TypeInfo(supertype) 264 base_type_info = self._type_registry.TypeInfo(supertype)
319 if base_type_info.merged_into() \ 265 if base_type_info.merged_into() \
320 and self._backend.ImplementsMergedMembers(): 266 and self._backend.ImplementsMergedMembers():
321 base_type_info = self._type_registry.TypeInfo( 267 base_type_info = self._type_registry.TypeInfo(
322 base_type_info.merged_into()) 268 base_type_info.merged_into())
323 269
324 if base_type_info: 270 if base_type_info:
325 base_class = base_type_info.implementation_name() 271 base_class = base_type_info.implementation_name()
326 else: 272 else:
327 base_class = self._backend.RootClassName() 273 base_class = self._backend.RootClassName()
328 274
329 implements = self._backend.AdditionalImplementedInterfaces() 275 implements = self._backend.AdditionalImplementedInterfaces()
330 for parent in self._interface.parents: 276 for parent in self._interface.parents:
331 parent_type_info = self._type_registry.TypeInfo(parent.type.id) 277 parent_type_info = self._type_registry.TypeInfo(parent.type.id)
332 if parent_type_info != base_type_info: 278 if parent_type_info != base_type_info:
333 implements.append(parent_type_info.interface_name()) 279 implements.append(parent_type_info.interface_name())
334 280
335 if interface_name in _secure_base_types: 281 secure_base_name = self._backend.SecureBaseName(interface_name)
336 implements.append(_secure_base_types[interface_name]) 282 if secure_base_name:
283 implements.append(secure_base_name)
337 284
338 implements_str = '' 285 implements_str = ''
339 if implements: 286 if implements:
340 implements_str = ' implements ' + ', '.join(set(implements)) 287 implements_str = ' implements ' + ', '.join(set(implements))
341 288
342 self._implementation_members_emitter = implementation_emitter.Emit( 289 self._implementation_members_emitter = implementation_emitter.Emit(
343 self._backend.ImplementationTemplate(), 290 self._backend.ImplementationTemplate(),
344 CLASSNAME=self._interface_type_info.implementation_name(), 291 CLASSNAME=self._interface_type_info.implementation_name(),
345 EXTENDS=' extends %s' % base_class if base_class else '', 292 EXTENDS=' extends %s' % base_class if base_class else '',
346 IMPLEMENTS=implements_str, 293 IMPLEMENTS=implements_str,
347 DOMNAME=self._interface.doc_js_name, 294 DOMNAME=self._interface.doc_js_name,
348 NATIVESPEC=self._backend.NativeSpec()) 295 NATIVESPEC=self._backend.NativeSpec())
349 self._backend.StartInterface(self._implementation_members_emitter) 296 self._backend.StartInterface(self._implementation_members_emitter)
350 297
351 for constructor_info in constructors:
352 constructor_info.GenerateFactoryInvocation(
353 self._DartType, self._members_emitter, factory_provider)
354
355 self._backend.AddConstructors(constructors, factory_provider, 298 self._backend.AddConstructors(constructors, factory_provider,
356 self._interface_type_info.implementation_name(), 299 self._interface_type_info.implementation_name(),
357 base_class) 300 base_class)
358 301
359 typed_array_type = None 302 events_class_name = self._event_generator.ProcessInterface(
360 for interface in self._database.Hierarchy(self._interface):
361 type_info = self._type_registry.TypeInfo(interface.id)
362 if type_info.is_typed_array():
363 typed_array_type = type_info.list_item_type()
364 break
365 if typed_array_type:
366 self._members_emitter.Emit(
367 '\n'
368 ' factory $CTOR(int length) =>\n'
369 ' $FACTORY.create$(CTOR)(length);\n'
370 '\n'
371 ' factory $CTOR.fromList(List<$TYPE> list) =>\n'
372 ' $FACTORY.create$(CTOR)_fromList(list);\n'
373 '\n'
374 ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int l ength]) => \n'
375 ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n' ,
376 CTOR=self._interface.id,
377 TYPE=self._DartType(typed_array_type),
378 FACTORY=factory_provider)
379
380 events_interface = self._event_generator.ProcessInterface(
381 self._interface, interface_name, 303 self._interface, interface_name,
382 self._backend.CustomJSMembers(), 304 self._backend.CustomJSMembers(),
383 interface_emitter, implementation_emitter) 305 implementation_emitter)
384 if events_interface: 306 if events_class_name:
385 self._EmitEventGetter(events_interface, events_interface) 307 self._backend.EmitEventGetter(events_class_name)
386 308
387 old_backend = self._backend
388 if not self._backend.ImplementsMergedMembers():
389 self._backend = HtmlGeneratorDummyBackend()
390 merged_interface = self._interface_type_info.merged_interface() 309 merged_interface = self._interface_type_info.merged_interface()
391 if merged_interface: 310 if merged_interface:
392 self.AddMembers(self._database.GetInterface(merged_interface)) 311 self._backend.AddMembers(self._database.GetInterface(merged_interface),
393 self._backend = old_backend 312 not self._backend.ImplementsMergedMembers())
394 313
395 self.AddMembers(self._interface) 314 self._backend.AddMembers(self._interface)
396 if merged_interface and not self._backend.ImplementsMergedMembers(): 315 self._backend.AddSecondaryMembers(self._interface)
397 self.AddMembers(self._database.GetInterface(merged_interface), True)
398
399 self.AddSecondaryMembers(self._interface)
400 self._backend.FinishInterface() 316 self._backend.FinishInterface()
401 317
402 def AddMembers(self, interface, declare_only=False):
403 for const in sorted(interface.constants, ConstantOutputOrder):
404 self.AddConstant(const)
405
406 for attr in sorted(interface.attributes, ConstantOutputOrder):
407 if attr.type.id != 'EventListener':
408 self.AddAttribute(attr, False, declare_only)
409
410 # The implementation should define an indexer if the interface directly
411 # extends List.
412 element_type = None
413 requires_indexer = False
414 if self._interface_type_info.list_item_type():
415 self.AddIndexer(self._interface_type_info.list_item_type())
416 else:
417 for parent in self._database.Hierarchy(self._interface):
418 if parent == self._interface:
419 continue
420 parent_type_info = self._type_registry.TypeInfo(parent.id)
421 if parent_type_info.list_item_type():
422 self.AmendIndexer(parent_type_info.list_item_type())
423 break
424
425 # Group overloaded operations by id
426 operationsById = {}
427 for operation in interface.operations:
428 if operation.id not in operationsById:
429 operationsById[operation.id] = []
430 operationsById[operation.id].append(operation)
431
432 # Generate operations
433 for id in sorted(operationsById.keys()):
434 operations = operationsById[id]
435 info = AnalyzeOperation(interface, operations)
436 self.AddOperation(info, False, declare_only)
437
438 def AddSecondaryMembers(self, interface):
439 # With multiple inheritance, attributes and operations of non-first
440 # interfaces need to be added. Sometimes the attribute or operation is
441 # defined in the current interface as well as a parent. In that case we
442 # avoid making a duplicate definition and pray that the signatures match.
443 secondary_parents = self._TransitiveSecondaryParents(interface)
444 for parent_interface in sorted(secondary_parents):
445 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter face)
446 continue
447 for attr in sorted(parent_interface.attributes, ConstantOutputOrder):
448 if not FindMatchingAttribute(interface, attr):
449 self.AddSecondaryAttribute(parent_interface, attr)
450
451 # Group overloaded operations by id
452 operationsById = {}
453 for operation in parent_interface.operations:
454 if operation.id not in operationsById:
455 operationsById[operation.id] = []
456 operationsById[operation.id].append(operation)
457
458 # Generate operations
459 for id in sorted(operationsById.keys()):
460 if not any(op.id == id for op in interface.operations):
461 operations = operationsById[id]
462 info = AnalyzeOperation(interface, operations)
463 self.AddSecondaryOperation(parent_interface, info)
464
465 def AddIndexer(self, element_type):
466 self._backend.AddIndexer(element_type)
467
468 def AmendIndexer(self, element_type):
469 self._backend.AmendIndexer(element_type)
470
471 def AddAttribute(self, attribute, is_secondary=False, declare_only=False):
472 dom_name = DartDomNameOfAttribute(attribute)
473 html_name = self._renamer.RenameMember(
474 self._interface.id, attribute, dom_name, 'get:')
475 if not html_name or self._IsPrivate(html_name):
476 return
477
478
479 html_setter_name = self._renamer.RenameMember(
480 self._interface.id, attribute, dom_name, 'set:')
481 read_only = (attribute.is_read_only or 'Replaceable' in attribute.ext_attrs
482 or not html_setter_name)
483
484 # We don't yet handle inconsistent renames of the getter and setter yet.
485 assert(not html_setter_name or html_name == html_setter_name)
486
487 if not is_secondary:
488 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
489 DOMINTERFACE=attribute.doc_js_interface_name,
490 DOMNAME=dom_name)
491 if read_only:
492 template = '\n $TYPE get $NAME;\n'
493 else:
494 template = '\n $TYPE $NAME;\n'
495
496 self._members_emitter.Emit(template,
497 NAME=html_name,
498 TYPE=SecureOutputType(self, attribute.type.id))
499
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)
505
506 def AddSecondaryAttribute(self, interface, attribute):
507 self._backend.SecondaryContext(interface)
508 self.AddAttribute(attribute, True)
509
510 def AddOperation(self, info, skip_declaration=False, declare_only=False):
511 """
512 Arguments:
513 operations - contains the overloads, one or more operations with the same
514 name.
515 """
516 # FIXME: When we pass in operations[0] below, we're assuming all
517 # overloaded operations have the same security attributes. This
518 # is currently true, but we should consider filtering earlier or
519 # merging the relevant data into info itself.
520 html_name = self._renamer.RenameMember(self._interface.id,
521 info.operations[0],
522 info.name)
523 if not html_name:
524 if info.name == 'item':
525 # FIXME: item should be renamed to operator[], not removed.
526 self._backend.AddOperation(info, '_item')
527 return
528
529 if not self._IsPrivate(html_name) and not skip_declaration:
530 self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
531 DOMINTERFACE=info.overloads[0].doc_js_interface_name,
532 DOMNAME=info.name)
533
534 if info.IsStatic():
535 # FIXME: provide a type.
536 self._members_emitter.Emit(
537 '\n'
538 ' static final $NAME = $IMPL_CLASS_NAME.$NAME;\n',
539 IMPL_CLASS_NAME=self._interface_type_info.implementation_name(),
540 NAME=html_name)
541 else:
542 self._members_emitter.Emit(
543 '\n'
544 ' $TYPE $NAME($PARAMS);\n',
545 TYPE=SecureOutputType(self, info.type_name),
546 NAME=html_name,
547 PARAMS=info.ParametersDeclaration(self._DartType))
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)
553
554 def AddSecondaryOperation(self, interface, info):
555 self._backend.SecondaryContext(interface)
556 self.AddOperation(info)
557
558 def AddConstant(self, constant):
559 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
560 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
561 NAME=constant.id,
562 TYPE=type,
563 VALUE=constant.value)
564
565 self._backend.AddConstant(constant)
566
567 def _ImplementationEmitter(self): 318 def _ImplementationEmitter(self):
568 basename = self._interface_type_info.implementation_name() 319 basename = self._interface_type_info.implementation_name()
569 if (self._interface_type_info.merged_into() and 320 if (self._interface_type_info.merged_into() and
570 self._backend.ImplementsMergedMembers()): 321 self._backend.ImplementsMergedMembers()):
571 # Merged members are implemented in target interface implementation. 322 # Merged members are implemented in target interface implementation.
572 return emitter.Emitter() 323 return emitter.Emitter()
573 return self._library_emitter.FileEmitter(basename) 324 return self._library_emitter.FileEmitter(basename)
574 325
575 def _EmitEventGetter(self, events_interface, events_class):
576 self._members_emitter.Emit(
577 '\n /**'
578 '\n * @domName EventTarget.addEventListener, '
579 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
580 '\n */'
581 '\n $TYPE get on;\n',
582 TYPE=events_interface)
583
584 self._implementation_members_emitter.Emit(
585 '\n /**'
586 '\n * @domName EventTarget.addEventListener, '
587 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
588 '\n */'
589 '\n $TYPE get on =>\n new $TYPE(this);\n',
590 TYPE=events_class)
591
592 def _TransitiveSecondaryParents(self, interface):
593 """Returns a list of all non-primary parents.
594
595 The list contains the interface objects for interfaces defined in the
596 database, and the name for undefined interfaces.
597 """
598 def walk(parents):
599 for parent in parents:
600 parent_name = parent.type.id
601 if parent_name == 'EventTarget':
602 # Currently EventTarget is implemented as a mixin, not a proper
603 # super interface---ignore its members.
604 continue
605 if IsDartCollectionType(parent_name):
606 result.append(parent_name)
607 continue
608 if self._database.HasInterface(parent_name):
609 parent_interface = self._database.GetInterface(parent_name)
610 result.append(parent_interface)
611 walk(parent_interface.parents)
612
613 result = []
614 if interface.parents:
615 parent = interface.parents[0]
616 if IsPureInterface(parent.type.id):
617 walk(interface.parents)
618 else:
619 walk(interface.parents[1:])
620 return result
621
622 def _DartType(self, type_name): 326 def _DartType(self, type_name):
623 return self._type_registry.DartType(type_name) 327 return self._type_registry.DartType(type_name)
624 328
625 def _IsPrivate(self, name):
626 return name.startswith('_')
627
628
629 class HtmlGeneratorDummyBackend(object):
630 def AddAttribute(self, attribute, html_name, read_only):
631 pass
632
633 def AddOperation(self, info, html_name):
634 pass
635
636 329
637 # ------------------------------------------------------------------------------ 330 # ------------------------------------------------------------------------------
638 331
639 class Dart2JSBackend(HtmlDartGenerator): 332 class Dart2JSBackend(HtmlDartGenerator):
640 """Generates a dart2js class for the dart:html library from a DOM IDL 333 """Generates a dart2js class for the dart:html library from a DOM IDL
641 interface. 334 interface.
642 """ 335 """
643 336
644 def __init__(self, interface, options): 337 def __init__(self, interface, options):
645 super(Dart2JSBackend, self).__init__(interface, options) 338 super(Dart2JSBackend, self).__init__(interface, options)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 # 418 #
726 # class YImpl extends XImpl { add List<T> methods; } 419 # class YImpl extends XImpl { add List<T> methods; }
727 # 420 #
728 # and 421 # and
729 # 422 #
730 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; } 423 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
731 # 424 #
732 self._members_emitter.Emit( 425 self._members_emitter.Emit(
733 '\n' 426 '\n'
734 ' $TYPE operator[](int index) => JS("$TYPE", "#[#]", this, index);\n', 427 ' $TYPE operator[](int index) => JS("$TYPE", "#[#]", this, index);\n',
735 TYPE=self._NarrowOutputType(element_type)) 428 TYPE=self.SecureOutputType(element_type))
736 429
737 if 'CustomIndexedSetter' in self._interface.ext_attrs: 430 if 'CustomIndexedSetter' in self._interface.ext_attrs:
738 self._members_emitter.Emit( 431 self._members_emitter.Emit(
739 '\n' 432 '\n'
740 ' void operator[]=(int index, $TYPE value) =>' 433 ' void operator[]=(int index, $TYPE value) =>'
741 ' JS("void", "#[#] = #", this, index, value);\n', 434 ' JS("void", "#[#] = #", this, index, value);\n',
742 TYPE=self._NarrowInputType(element_type)) 435 TYPE=self._NarrowInputType(element_type))
743 else: 436 else:
744 # The HTML library implementation of NodeList has a custom indexed setter 437 # The HTML library implementation of NodeList has a custom indexed setter
745 # implementation that uses the parent node the NodeList is associated 438 # implementation that uses the parent node the NodeList is associated
746 # with if one is available. 439 # with if one is available.
747 if self._interface.id != 'NodeList': 440 if self._interface.id != 'NodeList':
748 self._members_emitter.Emit( 441 self._members_emitter.Emit(
749 '\n' 442 '\n'
750 ' void operator[]=(int index, $TYPE value) {\n' 443 ' void operator[]=(int index, $TYPE value) {\n'
751 ' throw new UnsupportedError("Cannot assign element of immutable List.");\n' 444 ' throw new UnsupportedError("Cannot assign element of immutable List.");\n'
752 ' }\n', 445 ' }\n',
753 TYPE=self._NarrowInputType(element_type)) 446 TYPE=self._NarrowInputType(element_type))
754 447
755 # TODO(sra): Use separate mixins for mutable implementations of List<T>. 448 # TODO(sra): Use separate mixins for mutable implementations of List<T>.
756 # TODO(sra): Use separate mixins for typed array implementations of List<T>. 449 # TODO(sra): Use separate mixins for typed array implementations of List<T>.
757 if self._interface.id != 'NodeList': 450 if self._interface.id != 'NodeList':
758 template_file = 'immutable_list_mixin.darttemplate' 451 template_file = 'immutable_list_mixin.darttemplate'
759 has_contains = any(op.id == 'contains' for op in self._interface.operation s) 452 has_contains = any(op.id == 'contains' for op in self._interface.operation s)
760 template = self._template_loader.Load( 453 template = self._template_loader.Load(
761 template_file, 454 template_file,
762 {'DEFINE_CONTAINS': not has_contains}) 455 {'DEFINE_CONTAINS': not has_contains})
763 self._members_emitter.Emit(template, E=self._DartType(element_type)) 456 self._members_emitter.Emit(template, E=self._DartType(element_type))
764 457
765 def AddAttribute(self, attribute, html_name, read_only): 458 def EmitAttribute(self, attribute, html_name, read_only):
766 if self._HasCustomImplementation(attribute.id): 459 if self._HasCustomImplementation(attribute.id):
767 return 460 return
768 461
769 if IsPureInterface(self._interface.id): 462 if IsPureInterface(self._interface.id):
770 self._AddInterfaceAttribute(attribute) 463 self._AddInterfaceAttribute(attribute)
771 return 464 return
772 465
773 if attribute.id != html_name: 466 if attribute.id != html_name:
774 self._AddAttributeUsingProperties(attribute, html_name, read_only) 467 self._AddAttributeUsingProperties(attribute, html_name, read_only)
775 return 468 return
(...skipping 10 matching lines...) Expand all
786 if read_only: 479 if read_only:
787 if attribute.type.id == super_attribute.type.id: 480 if attribute.type.id == super_attribute.type.id:
788 # Compatible attribute, use the superclass property. This works 481 # Compatible attribute, use the superclass property. This works
789 # because JavaScript will do its own dynamic dispatch. 482 # because JavaScript will do its own dynamic dispatch.
790 self._members_emitter.Emit( 483 self._members_emitter.Emit(
791 '\n' 484 '\n'
792 ' // Use implementation from $SUPER.\n' 485 ' // Use implementation from $SUPER.\n'
793 ' // final $TYPE $NAME;\n', 486 ' // final $TYPE $NAME;\n',
794 SUPER=super_attribute_interface, 487 SUPER=super_attribute_interface,
795 NAME=DartDomNameOfAttribute(attribute), 488 NAME=DartDomNameOfAttribute(attribute),
796 TYPE=self._NarrowOutputType(attribute.type.id)) 489 TYPE=self.SecureOutputType(attribute.type.id))
797 return 490 return
798 self._members_emitter.Emit('\n // Shadowing definition.') 491 self._members_emitter.Emit('\n // Shadowing definition.')
799 self._AddAttributeUsingProperties(attribute, html_name, read_only) 492 self._AddAttributeUsingProperties(attribute, html_name, read_only)
800 return 493 return
801 494
802 # If the type has a conversion we need a getter or setter to contain the 495 # If the type has a conversion we need a getter or setter to contain the
803 # conversion code. 496 # conversion code.
804 if (self._OutputConversion(attribute.type.id, attribute.id) or 497 if (self._OutputConversion(attribute.type.id, attribute.id) or
805 self._InputConversion(attribute.type.id, attribute.id)): 498 self._InputConversion(attribute.type.id, attribute.id)):
806 self._AddAttributeUsingProperties(attribute, html_name, read_only) 499 self._AddAttributeUsingProperties(attribute, html_name, read_only)
807 return 500 return
808 501
809 output_type = self._NarrowOutputType(attribute.type.id) 502 output_type = self.SecureOutputType(attribute.type.id)
810 input_type = self._NarrowInputType(attribute.type.id) 503 input_type = self._NarrowInputType(attribute.type.id)
811 self.EmitAttributeDocumentation(attribute) 504 self.EmitAttributeDocumentation(attribute)
812 if not read_only: 505 if not read_only:
813 self._members_emitter.Emit( 506 self._members_emitter.Emit(
814 '\n $TYPE $NAME;' 507 '\n $TYPE $NAME;'
815 '\n', 508 '\n',
816 NAME=DartDomNameOfAttribute(attribute), 509 NAME=DartDomNameOfAttribute(attribute),
817 TYPE=output_type) 510 TYPE=output_type)
818 else: 511 else:
819 self._members_emitter.Emit( 512 self._members_emitter.Emit(
820 '\n final $TYPE $NAME;' 513 '\n final $TYPE $NAME;'
821 '\n', 514 '\n',
822 NAME=DartDomNameOfAttribute(attribute), 515 NAME=DartDomNameOfAttribute(attribute),
823 TYPE=output_type) 516 TYPE=output_type)
824 517
825 def _AddAttributeUsingProperties(self, attribute, html_name, read_only): 518 def _AddAttributeUsingProperties(self, attribute, html_name, read_only):
826 self._AddRenamingGetter(attribute, html_name) 519 self._AddRenamingGetter(attribute, html_name)
827 if not read_only: 520 if not read_only:
828 self._AddRenamingSetter(attribute, html_name) 521 self._AddRenamingSetter(attribute, html_name)
829 522
830 def _AddInterfaceAttribute(self, attribute): 523 def _AddInterfaceAttribute(self, attribute):
831 self._members_emitter.Emit( 524 self._members_emitter.Emit(
832 '\n $TYPE $NAME;' 525 '\n $TYPE $NAME;'
833 '\n', 526 '\n',
834 NAME=DartDomNameOfAttribute(attribute), 527 NAME=DartDomNameOfAttribute(attribute),
835 TYPE=self._NarrowOutputType(attribute.type.id)) 528 TYPE=self.SecureOutputType(attribute.type.id))
836 529
837 def _AddRenamingGetter(self, attr, html_name): 530 def _AddRenamingGetter(self, attr, html_name):
838 self.EmitAttributeDocumentation(attr) 531 self.EmitAttributeDocumentation(attr)
839 532
840 conversion = self._OutputConversion(attr.type.id, attr.id) 533 conversion = self._OutputConversion(attr.type.id, attr.id)
841 if conversion: 534 if conversion:
842 return self._AddConvertingGetter(attr, html_name, conversion) 535 return self._AddConvertingGetter(attr, html_name, conversion)
843 return_type = self._NarrowOutputType(attr.type.id) 536 return_type = self.SecureOutputType(attr.type.id)
844 self._members_emitter.Emit( 537 self._members_emitter.Emit(
845 # TODO(sra): Use metadata to provide native name. 538 # TODO(sra): Use metadata to provide native name.
846 '\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);' 539 '\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);'
847 '\n', 540 '\n',
848 HTML_NAME=html_name, 541 HTML_NAME=html_name,
849 NAME=attr.id, 542 NAME=attr.id,
850 TYPE=return_type) 543 TYPE=return_type)
851 544
852 def _AddRenamingSetter(self, attr, html_name): 545 def _AddRenamingSetter(self, attr, html_name):
853 self.EmitAttributeDocumentation(attr) 546 self.EmitAttributeDocumentation(attr)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 '\n', 583 '\n',
891 CONVERT=conversion.function_name, 584 CONVERT=conversion.function_name,
892 HTML_NAME=html_name, 585 HTML_NAME=html_name,
893 NAME=attr.id, 586 NAME=attr.id,
894 INPUT_TYPE=conversion.input_type, 587 INPUT_TYPE=conversion.input_type,
895 NATIVE_TYPE=conversion.output_type) 588 NATIVE_TYPE=conversion.output_type)
896 589
897 def AmendIndexer(self, element_type): 590 def AmendIndexer(self, element_type):
898 pass 591 pass
899 592
900 def AddOperation(self, info, html_name): 593 def EmitOperation(self, info, html_name):
901 """ 594 """
902 Arguments: 595 Arguments:
903 info: An OperationInfo object. 596 info: An OperationInfo object.
904 """ 597 """
905 if self._HasCustomImplementation(info.name): 598 if self._HasCustomImplementation(info.name):
906 return 599 return
907 600
908 self.EmitOperationDocumentation(info) 601 self.EmitOperationDocumentation(info)
909 602
910 if IsPureInterface(self._interface.id): 603 if IsPureInterface(self._interface.id):
911 self._AddInterfaceOperation(info, html_name) 604 self._AddInterfaceOperation(info, html_name)
912 elif any(self._OperationRequiresConversions(op) for op in info.overloads): 605 elif any(self._OperationRequiresConversions(op) for op in info.overloads):
913 # Any conversions needed? 606 # Any conversions needed?
914 self._AddOperationWithConversions(info, html_name) 607 self._AddOperationWithConversions(info, html_name)
915 else: 608 else:
916 self._AddDirectNativeOperation(info, html_name) 609 self._AddDirectNativeOperation(info, html_name)
917 610
918 def _AddDirectNativeOperation(self, info, html_name): 611 def _AddDirectNativeOperation(self, info, html_name):
919 # Do we need a native body? 612 # Do we need a native body?
920 if html_name != info.declared_name: 613 if html_name != info.declared_name:
921 return_type = self._NarrowOutputType(info.type_name) 614 return_type = self.SecureOutputType(info.type_name)
922 615
923 operation_emitter = self._members_emitter.Emit('$!SCOPE', 616 operation_emitter = self._members_emitter.Emit('$!SCOPE',
924 MODIFIERS='static ' if info.IsStatic() else '', 617 MODIFIERS='static ' if info.IsStatic() else '',
925 TYPE=return_type, 618 TYPE=return_type,
926 HTML_NAME=html_name, 619 HTML_NAME=html_name,
927 NAME=info.declared_name, 620 NAME=info.declared_name,
928 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) 621 PARAMS=info.ParametersDeclaration(self._NarrowInputType))
929 622
930 operation_emitter.Emit( 623 operation_emitter.Emit(
931 '\n' 624 '\n'
932 #' // @native("$NAME")\n;' 625 #' // @native("$NAME")\n;'
933 ' $MODIFIERS$TYPE $(HTML_NAME)($PARAMS) native "$NAME";\n') 626 ' $MODIFIERS$TYPE $(HTML_NAME)($PARAMS) native "$NAME";\n')
934 else: 627 else:
935 self._members_emitter.Emit( 628 self._members_emitter.Emit(
936 '\n' 629 '\n'
937 ' $MODIFIERS$TYPE $NAME($PARAMS) native;\n', 630 ' $MODIFIERS$TYPE $NAME($PARAMS) native;\n',
938 MODIFIERS='static ' if info.IsStatic() else '', 631 MODIFIERS='static ' if info.IsStatic() else '',
939 TYPE=self._NarrowOutputType(info.type_name), 632 TYPE=self.SecureOutputType(info.type_name),
940 NAME=info.name, 633 NAME=info.name,
941 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) 634 PARAMS=info.ParametersDeclaration(self._NarrowInputType))
942 635
943 def _AddOperationWithConversions(self, info, html_name): 636 def _AddOperationWithConversions(self, info, html_name):
944 # Assert all operations have same return type. 637 # Assert all operations have same return type.
945 assert len(set([op.type.id for op in info.operations])) == 1 638 assert len(set([op.type.id for op in info.operations])) == 1
946 info = info.CopyAndWidenDefaultParameters() 639 info = info.CopyAndWidenDefaultParameters()
947 output_conversion = self._OutputConversion(info.type_name, 640 output_conversion = self._OutputConversion(info.type_name,
948 info.declared_name) 641 info.declared_name)
949 if output_conversion: 642 if output_conversion:
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 if self._IsOptional(operation, argument): 769 if self._IsOptional(operation, argument):
1077 check = '?%s' % parameter_names[position] 770 check = '?%s' % parameter_names[position]
1078 GenerateCall(operation, position + 1, [check]) 771 GenerateCall(operation, position + 1, [check])
1079 argument_count = position 772 argument_count = position
1080 GenerateCall(operation, argument_count, []) 773 GenerateCall(operation, argument_count, [])
1081 774
1082 def _AddInterfaceOperation(self, info, html_name): 775 def _AddInterfaceOperation(self, info, html_name):
1083 self._members_emitter.Emit( 776 self._members_emitter.Emit(
1084 '\n' 777 '\n'
1085 ' $TYPE $NAME($PARAMS);\n', 778 ' $TYPE $NAME($PARAMS);\n',
1086 TYPE=self._NarrowOutputType(info.type_name), 779 TYPE=self.SecureOutputType(info.type_name),
1087 NAME=info.name, 780 NAME=info.name,
1088 PARAMS=info.ParametersDeclaration(self._NarrowInputType)) 781 PARAMS=info.ParametersDeclaration(self._NarrowInputType))
1089 782
1090 def AddConstant(self, constant): 783 def AddConstant(self, constant):
1091 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id) 784 type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
1092 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n', 785 self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
1093 NAME=constant.id, 786 NAME=constant.id,
1094 TYPE=type, 787 TYPE=type,
1095 VALUE=constant.value) 788 VALUE=constant.value)
1096 789
(...skipping 25 matching lines...) Expand all
1122 815
1123 def CustomJSMembers(self): 816 def CustomJSMembers(self):
1124 return _js_custom_members 817 return _js_custom_members
1125 818
1126 def _NarrowToImplementationType(self, type_name): 819 def _NarrowToImplementationType(self, type_name):
1127 return self._type_registry.TypeInfo(type_name).narrow_dart_type() 820 return self._type_registry.TypeInfo(type_name).narrow_dart_type()
1128 821
1129 def _NarrowInputType(self, type_name): 822 def _NarrowInputType(self, type_name):
1130 return self._NarrowToImplementationType(type_name) 823 return self._NarrowToImplementationType(type_name)
1131 824
1132 def _NarrowOutputType(self, type_name):
1133 return SecureOutputType(self, type_name)
1134
1135 def _FindShadowedAttribute(self, attr): 825 def _FindShadowedAttribute(self, attr):
1136 """Returns (attribute, superinterface) or (None, None).""" 826 """Returns (attribute, superinterface) or (None, None)."""
1137 def FindInParent(interface): 827 def FindInParent(interface):
1138 """Returns matching attribute in parent, or None.""" 828 """Returns matching attribute in parent, or None."""
1139 if interface.parents: 829 if interface.parents:
1140 parent = interface.parents[0] 830 parent = interface.parents[0]
1141 if IsDartCollectionType(parent.type.id): 831 if IsDartCollectionType(parent.type.id):
1142 return (None, None) 832 return (None, None)
1143 if IsPureInterface(parent.type.id): 833 if IsPureInterface(parent.type.id):
1144 return (None, None) 834 return (None, None)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 886
1197 library_emitter = self._multiemitter.FileEmitter(library_file_path) 887 library_emitter = self._multiemitter.FileEmitter(library_file_path)
1198 library_file_dir = os.path.dirname(library_file_path) 888 library_file_dir = os.path.dirname(library_file_path)
1199 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) 889 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir)
1200 imports_emitter = library_emitter.Emit( 890 imports_emitter = library_emitter.Emit(
1201 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) 891 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir))
1202 for path in sorted(self._path_to_emitter.keys()): 892 for path in sorted(self._path_to_emitter.keys()):
1203 relpath = os.path.relpath(path, library_file_dir) 893 relpath = os.path.relpath(path, library_file_dir)
1204 imports_emitter.Emit( 894 imports_emitter.Emit(
1205 "part '$PATH';\n", PATH=massage_path(relpath)) 895 "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