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

Side by Side Diff: sky/engine/bindings2/scripts/idlnode.py

Issue 914413004: Add a new bindings2/scripts directory for Dart bindings (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Remove idlrenderer.py it's not used Created 5 years, 10 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
OLDNEW
(Empty)
1 #!/usr/bin/python
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file.
5
6 import os
7 import sys
8
9 import idl_definitions
10 from idl_types import IdlType, IdlUnionType, IdlArrayOrSequenceType
11
12 from compute_interfaces_info_overall import interfaces_info
13
14
15 new_asts = {}
16
17
18 _operation_suffix_map = {
19 '__getter__': "Getter",
20 '__setter__': "Setter",
21 '__delete__': "Deleter",
22 }
23
24 class IDLNode(object):
25 """Base class for all IDL elements.
26 IDLNode may contain various child nodes, and have properties. Examples
27 of IDLNode are interfaces, interface members, function arguments,
28 etc.
29 """
30
31 def __init__(self, ast):
32 """Initializes an IDLNode from a PegParser AST output."""
33 self.id = self._find_first(ast, 'Id') if ast is not None else None
34
35
36 def __repr__(self):
37 """Generates string of the form <class id extra extra ... 0x12345678>."""
38 extras = self._extra_repr()
39 if isinstance(extras, list):
40 extras = ' '.join([str(e) for e in extras])
41 try:
42 if self.id:
43 return '<%s %s 0x%x>' % (
44 type(self).__name__,
45 ('%s %s' % (self.id, extras)).strip(),
46 hash(self))
47 return '<%s %s 0x%x>' % (
48 type(self).__name__,
49 extras,
50 hash(self))
51 except Exception, e:
52 return "can't convert to string: %s" % e
53
54 def _extra_repr(self):
55 """Returns string of extra info for __repr__()."""
56 return ''
57
58 def __cmp__(self, other):
59 """Override default compare operation.
60 IDLNodes are equal if all their properties are equal."""
61 if other is None or not isinstance(other, IDLNode):
62 return 1
63 return self.__dict__.__cmp__(other.__dict__)
64
65 def reset_id(self, newId):
66 """Reset the id of the Node. This is typically done during a normalization
67 phase (e.g., "DOMWindow" -> "Window")."""
68 self.id = newId
69
70 def all(self, type_filter=None):
71 """Returns a list containing this node and all it child nodes
72 (recursive).
73
74 Args:
75 type_filter -- can be used to limit the results to a specific
76 node type (e.g. IDLOperation).
77 """
78 res = []
79 if type_filter is None or isinstance(self, type_filter):
80 res.append(self)
81 for v in self._all_subnodes():
82 if isinstance(v, IDLNode):
83 res.extend(v.all(type_filter))
84 elif isinstance(v, list):
85 for item in v:
86 if isinstance(item, IDLNode):
87 res.extend(item.all(type_filter))
88 return res
89
90 def _all_subnodes(self):
91 """Accessor used by all() to find subnodes."""
92 return self.__dict__.values()
93
94 def to_dict(self):
95 """Converts the IDLNode and its children into a dictionary.
96 This method is useful mostly for debugging and pretty printing.
97 """
98 res = {}
99 for (k, v) in self.__dict__.items():
100 if v == None or v == False or v == [] or v == {}:
101 # Skip empty/false members.
102 continue
103 elif isinstance(v, IDLDictNode) and not len(v):
104 # Skip empty dict sub-nodes.
105 continue
106 elif isinstance(v, list):
107 # Convert lists:
108 new_v = []
109 for sub_node in v:
110 if isinstance(sub_node, IDLNode):
111 # Convert sub-node:
112 new_v.append(sub_node.to_dict())
113 else:
114 new_v.append(sub_node)
115 v = new_v
116 elif isinstance(v, IDLNode):
117 # Convert sub-node:
118 v = v.to_dict()
119 res[k] = v
120 return res
121
122 def _find_all(self, ast, label, max_results=sys.maxint):
123 """Searches the AST for tuples with a given label. The PegParser
124 output is composed of lists and tuples, where the tuple 1st argument
125 is a label. If ast root is a list, will search recursively inside each
126 member in the list.
127
128 Args:
129 ast -- the AST to search.
130 label -- the label to look for.
131 res -- results are put into this list.
132 max_results -- maximum number of results.
133 """
134 res = []
135 if max_results <= 0:
136 return res
137
138 if isinstance(ast, list):
139 for childAst in ast:
140 if childAst and \
141 not(isinstance(childAst, dict)) and \
142 not(isinstance(childAst, str)) and \
143 not(isinstance(childAst, tuple)) and \
144 childAst.__module__ == "idl_definitions":
145 field_name = self._convert_label_to_field(label)
146 if hasattr(childAst, field_name):
147 field_value = getattr(childAst, field_name)
148 # It's an IdlType we need the string name of the type.
149 if field_name == 'idl_type':
150 field_value = getattr(field_value, 'base_type')
151 res.append(field_value)
152 else:
153 sub_res = self._find_all(childAst, label,
154 max_results - len(res))
155 res.extend(sub_res)
156 elif isinstance(ast, tuple):
157 (nodeLabel, value) = ast
158 if nodeLabel == label:
159 res.append(value)
160 # TODO(terry): Seems bogus to check for so many things probably better to ju st
161 # pass in blink_compile and drive it off from that...
162 elif (ast and not(isinstance(ast, dict)) and
163 not(isinstance(ast, str)) and
164 (ast.__module__ == "idl_definitions" or ast.__module__ == "idl_types") ):
165 field_name = self._convert_label_to_field(label)
166 if hasattr(ast, field_name):
167 field_value = getattr(ast, field_name)
168 if field_value:
169 if label == 'Interface' or label == 'Enum':
170 for key in field_value:
171 value = field_value[key]
172 res.append(value)
173 elif isinstance(field_value, list):
174 for item in field_value:
175 res.append(item)
176 elif label == 'ParentInterface' or label == 'InterfaceType':
177 # Fetch the AST for the parent interface.
178 parent_idlnode = new_asts[field_value]
179 res.append(parent_idlnode.interfaces[field_value])
180 else:
181 res.append(field_value)
182
183 return res
184
185 def _find_first(self, ast, label):
186 """Convenience method for _find_all(..., max_results=1).
187 Returns a single element instead of a list, or None if nothing
188 is found."""
189 res = self._find_all(ast, label, max_results=1)
190 if len(res):
191 return res[0]
192 return None
193
194 def _has(self, ast, label):
195 """Returns true if an element with the given label is
196 in the AST by searching for it."""
197 return len(self._find_all(ast, label, max_results=1)) == 1
198
199 # Mapping from original AST tuple names to new AST field names idl_definitions .Idl*.
200 def _convert_label_to_field(self, label):
201 label_field = {
202 # Keys old AST names, Values Blink IdlInterface names.
203 'ParentInterface': 'parent',
204 'Id': 'name',
205 'Interface': 'interfaces',
206 'Callback': 'is_callback',
207 'Partial': 'is_partial',
208 'Operation': 'operations',
209 'Attribute': 'attributes',
210 'Const': 'constants',
211 'Type': 'idl_type',
212 'ExtAttrs': 'extended_attributes',
213 'Special': 'specials',
214 'ReturnType': 'idl_type',
215 'Argument': 'arguments',
216 'InterfaceType': 'name',
217 'ConstExpr': 'value',
218 'Static': 'is_static',
219 'ReadOnly': 'is_read_only',
220 'Optional': 'is_optional',
221 'Nullable': 'is_nullable',
222 'Enum': 'enumerations',
223 'Annotation': '', # TODO(terry): Ignore annotation used for databa se cache.
224 'TypeDef': '', # typedef in an IDL are already resolved.
225 }
226 result = label_field.get(label)
227 if result != '' and not(result):
228 print 'FATAL ERROR: AST mapping name not found %s.' % label
229 return result if result else ''
230
231 def _convert_all(self, ast, label, idlnode_ctor):
232 """Converts AST elements into IDLNode elements.
233 Uses _find_all to find elements with a given label and converts
234 them into IDLNodes with a given constructor.
235 Returns:
236 A list of the converted nodes.
237 Args:
238 ast -- the ast element to start a search at.
239 label -- the element label to look for.
240 idlnode_ctor -- a constructor function of one of the IDLNode
241 sub-classes.
242 """
243 res = []
244 found = self._find_all(ast, label)
245 if not found:
246 return res
247 if not isinstance(found, list):
248 raise RuntimeError("Expected list but %s found" % type(found))
249 for childAst in found:
250 converted = idlnode_ctor(childAst)
251 res.append(converted)
252 return res
253
254 def _convert_first(self, ast, label, idlnode_ctor):
255 """Like _convert_all, but only converts the first found results."""
256 childAst = self._find_first(ast, label)
257 if not childAst:
258 return None
259 return idlnode_ctor(childAst)
260
261 def _convert_ext_attrs(self, ast):
262 """Helper method for uniform conversion of extended attributes."""
263 self.ext_attrs = IDLExtAttrs(ast)
264
265 def _convert_annotations(self, ast):
266 """Helper method for uniform conversion of annotations."""
267 self.annotations = IDLAnnotations(ast)
268
269
270 class IDLDictNode(IDLNode):
271 """Base class for dictionary-like IDL nodes such as extended attributes
272 and annotations. The base class implements various dict interfaces."""
273
274 def __init__(self, ast):
275 IDLNode.__init__(self, None)
276 if ast is not None and isinstance(ast, dict):
277 self.__map = ast
278 else:
279 self.__map = {}
280
281 def __len__(self):
282 return len(self.__map)
283
284 def __getitem__(self, key):
285 return self.__map[key]
286
287 def __setitem__(self, key, value):
288 self.__map[key] = value
289
290 def __delitem__(self, key):
291 del self.__map[key]
292
293 def __contains__(self, key):
294 return key in self.__map
295
296 def __iter__(self):
297 return self.__map.__iter__()
298
299 def get(self, key, default=None):
300 return self.__map.get(key, default)
301
302 def setdefault(self, key, value=None):
303 return self.__map.setdefault(key, value)
304
305 def items(self):
306 return self.__map.items()
307
308 def keys(self):
309 return self.__map.keys()
310
311 def values(self):
312 return self.__map.values()
313
314 def clear(self):
315 self.__map = {}
316
317 def to_dict(self):
318 """Overrides the default IDLNode.to_dict behavior.
319 The IDLDictNode members are copied into a new dictionary, and
320 IDLNode members are recursively converted into dicts as well.
321 """
322 res = {}
323 for (k, v) in self.__map.items():
324 if isinstance(v, IDLNode):
325 v = v.to_dict()
326 res[k] = v
327 return res
328
329 def _all_subnodes(self):
330 # Usually an IDLDictNode does not contain further IDLNodes.
331 return []
332
333
334 class IDLFile(IDLNode):
335 """IDLFile is the top-level node in each IDL file. It may contain interfaces." ""
336
337 DART_IDL = 'dart.idl'
338
339 def __init__(self, ast, filename=None):
340 IDLNode.__init__(self, ast)
341 self.filename = filename
342
343 filename_basename = os.path.basename(filename)
344
345 self.interfaces = self._convert_all(ast, 'Interface', IDLInterface)
346
347 is_blink = not(isinstance(ast, list)) and ast.__module__ == 'idl_definitions '
348
349 if is_blink:
350 # implements is handled by the interface merging step (see the function
351 # merge_interface_dependencies).
352 for interface in self.interfaces:
353 blink_interface = ast.interfaces.get(interface.id)
354 if filename_basename == self.DART_IDL:
355 # Special handling for dart.idl we need to remember the interface,
356 # since we could have many (not one interface / file). Then build up
357 # the IDLImplementsStatement for any implements in dart.idl.
358 interface_info = interfaces_info['__dart_idl___'];
359
360 self.implementsStatements = []
361
362 implement_pairs = interface_info['implement_pairs']
363 for implement_pair in implement_pairs:
364 interface_name = implement_pair[0]
365 implemented_name = implement_pair[1]
366
367 implementor = new_asts[interface_name].interfaces.get(interface_name )
368 implement_statement = self._createImplementsStatement(implementor,
369 implemented_na me)
370
371 self.implementsStatements.append(implement_statement)
372 else:
373 interface_info = interfaces_info[interface.id]
374
375 implements = interface_info['implements_interfaces']
376 if not(blink_interface.is_partial) and len(implements) > 0:
377 implementor = new_asts[interface.id].interfaces.get(interface.id)
378
379 self.implementsStatements = []
380
381 # TODO(terry): Need to handle more than one implements.
382 for implemented_name in implements:
383 implement_statement = self._createImplementsStatement(implementor,
384 implemented_ name)
385 self.implementsStatements.append(implement_statement)
386 else:
387 self.implementsStatements = []
388 else:
389 self.implementsStatements = self._convert_all(ast, 'ImplStmt',
390 IDLImplementsStatement)
391
392 # No reason to handle typedef they're already aliased in Blink's AST.
393 self.typeDefs = [] if is_blink else self._convert_all(ast, 'TypeDef', IDLTyp eDef)
394
395 self.enums = self._convert_all(ast, 'Enum', IDLEnum)
396
397 def _createImplementsStatement(self, implementor, implemented_name):
398 implemented = new_asts[implemented_name].interfaces.get(implemented_name)
399
400 implement_statement = IDLImplementsStatement(implemented)
401
402 implement_statement.implementor = IDLType(implementor)
403 implement_statement.implemented = IDLType(implemented)
404
405 return implement_statement
406
407
408 class IDLModule(IDLNode):
409 """IDLModule has an id, and may contain interfaces, type defs and
410 implements statements."""
411 def __init__(self, ast):
412 IDLNode.__init__(self, ast)
413 self._convert_ext_attrs(ast)
414 self._convert_annotations(ast)
415 self.interfaces = self._convert_all(ast, 'Interface', IDLInterface)
416
417 is_blink = ast.__module__ == 'idl_definitions'
418
419 # No reason to handle typedef they're already aliased in Blink's AST.
420 self.typeDefs = [] if is_blink else self._convert_all(ast, 'TypeDef', IDLTyp eDef)
421
422 self.enums = self._convert_all(ast, 'Enum', IDLNode)
423
424 if is_blink:
425 # implements is handled by the interface merging step (see the function
426 # merge_interface_dependencies).
427 for interface in self.interfaces:
428 interface_info = interfaces_info[interface.id]
429 # TODO(terry): Same handling for implementsStatements as in IDLFile?
430 self.implementsStatements = interface_info['implements_interfaces']
431 else:
432 self.implementsStatements = self._convert_all(ast, 'ImplStmt',
433 IDLImplementsStatement)
434
435
436 class IDLExtAttrs(IDLDictNode):
437 """IDLExtAttrs is an IDLDictNode that stores IDL Extended Attributes.
438 Modules, interfaces, members and arguments can all own IDLExtAttrs."""
439 def __init__(self, ast=None):
440 IDLDictNode.__init__(self, None)
441 if not ast:
442 return
443 if not(isinstance(ast, list)) and ast.__module__ == "idl_definitions":
444 # Pull out extended attributes from Blink AST.
445 for name, value in ast.extended_attributes.items():
446 # TODO(terry): Handle constructors...
447 if name == 'NamedConstructor' or name == 'Constructor':
448 for constructor in ast.constructors:
449 if constructor.name == 'NamedConstructor':
450 constructor_name = ast.extended_attributes['NamedConstructor']
451 else:
452 constructor_name = None
453 func_value = IDLExtAttrFunctionValue(constructor_name, constructor.a rguments, True)
454 if name == 'Constructor':
455 self.setdefault('Constructor', []).append(func_value)
456 else:
457 self[name] = func_value
458 else:
459 self[name] = value
460 else:
461 ext_attrs_ast = self._find_first(ast, 'ExtAttrs')
462 if not ext_attrs_ast:
463 return
464 for ext_attr in self._find_all(ext_attrs_ast, 'ExtAttr'):
465 name = self._find_first(ext_attr, 'Id')
466 value = self._find_first(ext_attr, 'ExtAttrValue')
467
468 if name == 'Constructor':
469 # There might be multiple constructor attributes, collect them
470 # as a list. Represent plain Constructor attribute
471 # (without any signature) as None.
472 assert value is None
473 func_value = None
474 ctor_args = self._find_first(ext_attr, 'ExtAttrArgList')
475 if ctor_args:
476 func_value = IDLExtAttrFunctionValue(None, ctor_args)
477 self.setdefault('Constructor', []).append(func_value)
478 continue
479
480 func_value = self._find_first(value, 'ExtAttrFunctionValue')
481 if func_value:
482 # E.g. NamedConstructor=Audio(optional DOMString src)
483 self[name] = IDLExtAttrFunctionValue(
484 func_value,
485 self._find_first(func_value, 'ExtAttrArgList'))
486 continue
487
488 self[name] = value
489
490 def _all_subnodes(self):
491 # Extended attributes may contain IDLNodes, e.g. IDLExtAttrFunctionValue
492 return self.values()
493
494
495 class IDLExtAttrFunctionValue(IDLNode):
496 """IDLExtAttrFunctionValue."""
497 def __init__(self, func_value_ast, arg_list_ast, is_blink=False):
498 IDLNode.__init__(self, func_value_ast)
499 if is_blink:
500 # Blink path
501 self.id = func_value_ast # func_value_ast is the function name for Blink .
502 self.arguments = []
503 for argument in arg_list_ast:
504 self.arguments.append(IDLArgument(argument))
505 else:
506 self.arguments = self._convert_all(arg_list_ast, 'Argument', IDLArgument)
507
508
509 class IDLType(IDLNode):
510 """IDLType is used to describe constants, attributes and operations'
511 return and input types. IDLType matches AST labels such as ScopedName,
512 StringType, VoidType, IntegerType, etc."""
513
514 def __init__(self, ast):
515 IDLNode.__init__(self, ast)
516
517 self.nullable = self._has(ast, 'Nullable')
518 # Search for a 'ScopedName' or any label ending with 'Type'.
519 if isinstance(ast, list):
520 self.id = self._find_first(ast, 'ScopedName')
521 if not self.id:
522 # FIXME: use regexp search instead
523 def findType(ast):
524 for label, childAst in ast:
525 if label.endswith('Type'):
526 type = self._label_to_type(label, ast)
527 if type != 'sequence':
528 return type
529 type_ast = self._find_first(childAst, 'Type')
530 if not type_ast:
531 return type
532 return 'sequence<%s>' % findType(type_ast)
533 raise Exception('No type declaration found in %s' % ast)
534 self.id = findType(ast)
535 # TODO(terry): Remove array_modifiers id has [] appended, keep for old
536 # parsing.
537 array_modifiers = self._find_first(ast, 'ArrayModifiers')
538 if array_modifiers:
539 self.id += array_modifiers
540 elif isinstance(ast, tuple):
541 (label, value) = ast
542 if label == 'ScopedName':
543 self.id = value
544 else:
545 self.id = self._label_to_type(label, ast)
546 elif isinstance(ast, str):
547 self.id = ast
548 # New blink handling.
549 elif ast.__module__ == "idl_types":
550 if isinstance(ast, IdlType) or isinstance(ast, IdlArrayOrSequenceType):
551 type_name = str(ast)
552
553 # TODO(terry): For now don't handle unrestricted types see
554 # https://code.google.com/p/chromium/issues/detail?id=35429 8
555 type_name = type_name.replace('unrestricted ', '', 1);
556
557 # TODO(terry): Handled ScalarValueString as a DOMString.
558 type_name = type_name.replace('ScalarValueString', 'DOMString', 1)
559
560 self.id = type_name
561 else:
562 # IdlUnionType
563 if ast.is_union_type:
564 print 'WARNING type %s is union mapped to \'any\'' % self.id
565 # TODO(terry): For union types use any otherwise type is unionType is
566 # not found and is removed during merging.
567 self.id = 'any'
568 # TODO(terry): Any union type e.g. 'type1 or type2 or type2',
569 # 'typedef (Type1 or Type2) UnionType'
570 # Is a problem we need to extend IDLType and IDLTypeDef to handle more
571 # than one type.
572 #
573 # Also for typedef's e.g.,
574 # typedef (Type1 or Type2) UnionType
575 # should consider synthesizing a new interface (e.g., UnionType) that's
576 # both Type1 and Type2.
577 if not self.id:
578 print '>>>> __module__ %s' % ast.__module__
579 raise SyntaxError('Could not parse type %s' % (ast))
580
581 def _label_to_type(self, label, ast):
582 if label == 'LongLongType':
583 label = 'long long'
584 elif label.endswith('Type'):
585 # Omit 'Type' suffix and lowercase the rest.
586 label = '%s%s' % (label[0].lower(), label[1:-4])
587
588 # Add unsigned qualifier.
589 if self._has(ast, 'Unsigned'):
590 label = 'unsigned %s' % label
591 return label
592
593
594 class IDLEnum(IDLNode):
595 """IDLNode for 'enum [id] { [string]+ }'"""
596 def __init__(self, ast):
597 IDLNode.__init__(self, ast)
598 self._convert_annotations(ast)
599 if not(isinstance(ast, list)) and ast.__module__ == "idl_definitions":
600 # Blink AST
601 self.values = ast.values
602 else:
603 self.values = self._find_all(ast, 'StringLiteral')
604
605 # TODO(terry): Need to handle emitting of enums for dart:html
606
607
608 class IDLTypeDef(IDLNode):
609 """IDLNode for 'typedef [type] [id]' declarations."""
610 def __init__(self, ast):
611 IDLNode.__init__(self, ast)
612 self._convert_annotations(ast)
613 self.type = self._convert_first(ast, 'Type', IDLType)
614
615
616 class IDLInterface(IDLNode):
617 """IDLInterface node contains operations, attributes, constants,
618 as well as parent references."""
619
620 def __init__(self, ast):
621 IDLNode.__init__(self, ast)
622 self._convert_ext_attrs(ast)
623 self._convert_annotations(ast)
624
625 self.parents = self._convert_all(ast, 'ParentInterface',
626 IDLParentInterface)
627
628 javascript_interface_name = self.ext_attrs.get('InterfaceName', self.id)
629 self.javascript_binding_name = javascript_interface_name
630 self.doc_js_name = javascript_interface_name
631
632 if not (self._find_first(ast, 'Callback') is None):
633 self.ext_attrs['Callback'] = None
634 if not (self._find_first(ast, 'Partial') is None):
635 self.is_supplemental = True
636 self.ext_attrs['DartSupplemental'] = None
637
638 self.operations = self._convert_all(ast, 'Operation',
639 lambda ast: IDLOperation(ast, self.doc_js_name))
640 self.attributes = self._convert_all(ast, 'Attribute',
641 lambda ast: IDLAttribute(ast, self.doc_js_name))
642 self.constants = self._convert_all(ast, 'Const',
643 lambda ast: IDLConstant(ast, self.doc_js_name))
644 self.is_supplemental = 'DartSupplemental' in self.ext_attrs
645 self.is_no_interface_object = 'NoInterfaceObject' in self.ext_attrs
646
647
648 def reset_id(self, new_id):
649 """Reset the id of the Interface and corresponding the JS names."""
650 if self.id != new_id:
651 self.id = new_id
652 self.doc_js_name = new_id
653 self.javascript_binding_name = new_id
654 for member in self.operations:
655 member.doc_js_interface_name = new_id
656 for member in self.attributes:
657 member.doc_js_interface_name = new_id
658 for member in self.constants:
659 member.doc_js_interface_name = new_id
660
661 def has_attribute(self, candidate):
662 for attribute in self.attributes:
663 if (attribute.id == candidate.id and
664 attribute.is_read_only == candidate.is_read_only):
665 return True
666 return False
667
668
669 class IDLParentInterface(IDLNode):
670 """This IDLNode specialization is for 'Interface Child : Parent {}'
671 declarations."""
672 def __init__(self, ast):
673 IDLNode.__init__(self, ast)
674 self._convert_annotations(ast)
675 self.type = self._convert_first(ast, 'InterfaceType', IDLType)
676
677
678 class IDLMember(IDLNode):
679 """A base class for constants, attributes and operations."""
680
681 def __init__(self, ast, doc_js_interface_name):
682 IDLNode.__init__(self, ast)
683
684 self.type = self._convert_first(ast, 'Type', IDLType)
685 self._convert_ext_attrs(ast)
686 self._convert_annotations(ast)
687 self.doc_js_interface_name = doc_js_interface_name
688 self.is_static = self._has(ast, 'Static')
689
690
691 class IDLOperation(IDLMember):
692 """IDLNode specialization for 'type name(args)' declarations."""
693 def __init__(self, ast, doc_js_interface_name):
694 IDLMember.__init__(self, ast, doc_js_interface_name)
695
696 self.type = self._convert_first(ast, 'ReturnType', IDLType)
697 self.arguments = self._convert_all(ast, 'Argument', IDLArgument)
698 self.specials = self._find_all(ast, 'Special')
699 # Special case: there are getters of the form
700 # getter <ReturnType>(args). For now force the name to be __getter__,
701 # but it should be operator[] later.
702 if self.id is None:
703 if self.specials == ['getter']:
704 if self.ext_attrs.get('Custom') == 'PropertyQuery':
705 # Handling __propertyQuery__ the extended attribute is:
706 # [Custom=PropertyQuery] getter boolean (DOMString name);
707 self.id = '__propertyQuery__'
708 else:
709 self.id = '__getter__'
710 elif self.specials == ['setter']:
711 self.id = '__setter__'
712 # Special case: if it's a setter, ignore 'declared' return type
713 self.type = IDLType([('VoidType', None)])
714 elif self.specials == ['deleter']:
715 self.id = '__delete__'
716 else:
717 raise Exception('Cannot handle %s: operation has no id' % ast)
718
719 if len(self.arguments) >= 1 and (self.id in _operation_suffix_map) and not self.ext_attrs.get('ImplementedAs'):
720 arg = self.arguments[0]
721 operation_category = 'Named' if arg.type.id == 'DOMString' else 'Indexed '
722 self.ext_attrs.setdefault('ImplementedAs', 'anonymous%s%s' % (operation_ category, _operation_suffix_map[self.id]))
723
724 def _extra_repr(self):
725 return [self.arguments]
726
727 def SameSignatureAs(self, operation):
728 if self.type != operation.type:
729 return False
730 return [a.type for a in self.arguments] == [a.type for a in operation.argume nts]
731
732 class IDLAttribute(IDLMember):
733 """IDLNode specialization for 'attribute type name' declarations."""
734 def __init__(self, ast, doc_js_interface_name):
735 IDLMember.__init__(self, ast, doc_js_interface_name)
736 self.is_read_only = self._has(ast, 'ReadOnly')
737 # There are various ways to define exceptions for attributes:
738
739 def _extra_repr(self):
740 extra = []
741 if self.is_read_only: extra.append('readonly')
742 return extra
743
744
745 class IDLConstant(IDLMember):
746 """IDLNode specialization for 'const type name = value' declarations."""
747 def __init__(self, ast, doc_js_interface_name):
748 IDLMember.__init__(self, ast, doc_js_interface_name)
749 self.value = self._find_first(ast, 'ConstExpr')
750
751
752 class IDLArgument(IDLNode):
753 """IDLNode specialization for operation arguments."""
754 def __init__(self, ast):
755 IDLNode.__init__(self, ast)
756
757 self.default_value = None
758 self.default_value_is_null = False
759 # Handle the 'argType arg = default'. IDL syntax changed from
760 # [default=NullString].
761 if not isinstance(ast, list):
762 if isinstance(ast.default_value, idl_definitions.IdlLiteral) and ast.defau lt_value:
763 self.default_value = ast.default_value.value
764 self.default_value_is_null = ast.default_value.is_null
765 elif 'Default' in ast.extended_attributes:
766 # Work around [Default=Undefined] for arguments - only look in the model 's
767 # default_value
768 self.default_value = ast.extended_attributes.get('Default')
769 self.default_value_is_null = False
770
771 self.type = self._convert_first(ast, 'Type', IDLType)
772 self.optional = self._has(ast, 'Optional')
773 self._convert_ext_attrs(ast)
774 # TODO(vsm): Recover this from the type instead.
775 if 'Callback' in self.type.id:
776 self.ext_attrs['Callback'] = None
777
778 def __repr__(self):
779 return '<IDLArgument(type = %s, id = %s)>' % (self.type, self.id)
780
781
782 class IDLImplementsStatement(IDLNode):
783 """IDLNode specialization for 'IMPLEMENTOR implements IMPLEMENTED' declaration s."""
784 def __init__(self, ast):
785 IDLNode.__init__(self, ast)
786 if isinstance(ast, list) or ast.__module__ != 'idl_definitions':
787 self.implementor = self._convert_first(ast, 'ImplStmtImplementor', IDLType )
788 self.implemented = self._convert_first(ast, 'ImplStmtImplemented', IDLType )
789
790
791 class IDLAnnotations(IDLDictNode):
792 """IDLDictNode specialization for a list of FremontCut annotations."""
793 def __init__(self, ast=None):
794 IDLDictNode.__init__(self, ast)
795 self.id = None
796 if not ast:
797 return
798 for annotation in self._find_all(ast, 'Annotation'):
799 name = self._find_first(annotation, 'Id')
800 value = IDLAnnotation(annotation)
801 self[name] = value
802
803
804 class IDLAnnotation(IDLDictNode):
805 """IDLDictNode specialization for one annotation."""
806 def __init__(self, ast=None):
807 IDLDictNode.__init__(self, ast)
808 self.id = None
809 if not ast:
810 return
811 for arg in self._find_all(ast, 'AnnotationArg'):
812 name = self._find_first(arg, 'Id')
813 value = self._find_first(arg, 'AnnotationArgValue')
814 self[name] = value
OLDNEW
« no previous file with comments | « sky/engine/bindings2/scripts/idl_validator.py ('k') | sky/engine/bindings2/scripts/interface_dependency_resolver.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698