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

Side by Side Diff: sky/engine/bindings/scripts/idl_definitions.py

Issue 922053002: Remove unused V8 integration code in Sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: 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
« no previous file with comments | « sky/engine/bindings/scripts/idl_compiler.py ('k') | sky/engine/bindings/scripts/idl_reader.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 """Blink IDL Intermediate Representation (IR) classes.
30
31 Classes are primarily constructors, which build an IdlDefinitions object
32 (and various contained objects) from an AST (produced by blink_idl_parser).
33
34 This is in two steps:
35 * Constructors walk the AST, creating objects.
36 * Typedef resolution.
37
38 Typedefs are all resolved here, and not stored in IR.
39
40 Typedef resolution uses some auxiliary classes and OOP techniques to make this
41 a generic call, via the resolve_typedefs() method.
42
43 Class hierarchy (mostly containment, '<' for inheritance):
44
45 IdlDefinitions
46 IdlCallbackFunction < TypedObject
47 IdlEnum :: FIXME: remove, just use a dict for enums
48 IdlInterface
49 IdlAttribute < TypedObject
50 IdlConstant < TypedObject
51 IdlLiteral
52 IdlOperation < TypedObject
53 IdlArgument < TypedObject
54 IdlStringifier
55 IdlException < IdlInterface
56 (same contents as IdlInterface)
57
58 TypedObject :: mixin for typedef resolution
59
60 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
61 """
62
63 import abc
64
65 from idl_types import IdlType, IdlUnionType, IdlArrayType, IdlSequenceType, IdlN ullableType
66
67 SPECIAL_KEYWORD_LIST = ['GETTER', 'SETTER', 'DELETER']
68 STANDARD_TYPEDEFS = {
69 # http://www.w3.org/TR/WebIDL/#common-DOMTimeStamp
70 'DOMTimeStamp': 'unsigned long long',
71 }
72
73
74 ################################################################################
75 # TypedObject (mixin for typedef resolution)
76 ################################################################################
77
78 class TypedObject(object):
79 """Object with a type, such as an Attribute or Operation (return value).
80
81 The type can be an actual type, or can be a typedef, which must be resolved
82 before passing data to the code generator.
83 """
84 __metaclass__ = abc.ABCMeta
85 idl_type = None
86
87 def resolve_typedefs(self, typedefs):
88 """Resolve typedefs to actual types in the object."""
89 # Constructors don't have their own return type, because it's the
90 # interface itself.
91 if not self.idl_type:
92 return
93 # Need to re-assign self.idl_type, not just mutate idl_type,
94 # since type(idl_type) may change.
95 self.idl_type = self.idl_type.resolve_typedefs(typedefs)
96
97
98 ################################################################################
99 # Definitions (main container class)
100 ################################################################################
101
102 class IdlDefinitions(object):
103 def __init__(self, idl_name, node):
104 """Args: node: AST root node, class == 'File'"""
105 self.callback_functions = {}
106 self.dictionaries = {}
107 self.enumerations = {}
108 self.interfaces = {}
109 self.idl_name = idl_name
110
111 node_class = node.GetClass()
112 if node_class != 'File':
113 raise ValueError('Unrecognized node class: %s' % node_class)
114
115 typedefs = dict((typedef_name, IdlType(type_name))
116 for typedef_name, type_name in
117 STANDARD_TYPEDEFS.iteritems())
118
119 children = node.GetChildren()
120 for child in children:
121 child_class = child.GetClass()
122 if child_class == 'Interface':
123 interface = IdlInterface(idl_name, child)
124 self.interfaces[interface.name] = interface
125 elif child_class == 'Exception':
126 exception = IdlException(idl_name, child)
127 # For simplicity, treat exceptions as interfaces
128 self.interfaces[exception.name] = exception
129 elif child_class == 'Typedef':
130 type_name = child.GetName()
131 typedefs[type_name] = typedef_node_to_type(child)
132 elif child_class == 'Enum':
133 enumeration = IdlEnum(idl_name, child)
134 self.enumerations[enumeration.name] = enumeration
135 elif child_class == 'Callback':
136 callback_function = IdlCallbackFunction(idl_name, child)
137 self.callback_functions[callback_function.name] = callback_funct ion
138 elif child_class == 'Implements':
139 # Implements is handled at the interface merging step
140 pass
141 elif child_class == 'Dictionary':
142 dictionary = IdlDictionary(idl_name, child)
143 self.dictionaries[dictionary.name] = dictionary
144 else:
145 raise ValueError('Unrecognized node class: %s' % child_class)
146
147 # Typedefs are not stored in IR:
148 # Resolve typedefs with the actual types and then discard the Typedefs.
149 # http://www.w3.org/TR/WebIDL/#idl-typedefs
150 self.resolve_typedefs(typedefs)
151
152 def resolve_typedefs(self, typedefs):
153 for callback_function in self.callback_functions.itervalues():
154 callback_function.resolve_typedefs(typedefs)
155 for interface in self.interfaces.itervalues():
156 interface.resolve_typedefs(typedefs)
157
158 def update(self, other):
159 """Update with additional IdlDefinitions."""
160 for interface_name, new_interface in other.interfaces.iteritems():
161 if not new_interface.is_partial:
162 # Add as new interface
163 self.interfaces[interface_name] = new_interface
164 continue
165
166 # Merge partial to existing interface
167 try:
168 self.interfaces[interface_name].merge(new_interface)
169 except KeyError:
170 raise Exception('Tried to merge partial interface for {0}, '
171 'but no existing interface by that name'
172 .format(interface_name))
173
174 # Merge callbacks and enumerations
175 self.enumerations.update(other.enumerations)
176 self.callback_functions.update(other.callback_functions)
177
178
179 ################################################################################
180 # Callback Functions
181 ################################################################################
182
183 class IdlCallbackFunction(TypedObject):
184 def __init__(self, idl_name, node):
185 children = node.GetChildren()
186 num_children = len(children)
187 if num_children != 2:
188 raise ValueError('Expected 2 children, got %s' % num_children)
189 type_node, arguments_node = children
190 arguments_node_class = arguments_node.GetClass()
191 if arguments_node_class != 'Arguments':
192 raise ValueError('Expected Arguments node, got %s' % arguments_node_ class)
193
194 self.idl_name = idl_name
195 self.name = node.GetName()
196 self.idl_type = type_node_to_type(type_node)
197 self.arguments = arguments_node_to_arguments(idl_name, arguments_node)
198
199 def resolve_typedefs(self, typedefs):
200 TypedObject.resolve_typedefs(self, typedefs)
201 for argument in self.arguments:
202 argument.resolve_typedefs(typedefs)
203
204
205 ################################################################################
206 # Dictionary
207 ################################################################################
208
209 class IdlDictionary(object):
210 def __init__(self, idl_name, node):
211 self.extended_attributes = {}
212 self.is_partial = node.GetProperty('Partial') or False
213 self.idl_name = idl_name
214 self.name = node.GetName()
215 self.members = []
216 self.parent = None
217 for child in node.GetChildren():
218 child_class = child.GetClass()
219 if child_class == 'Inherit':
220 self.parent = child.GetName()
221 elif child_class == 'Key':
222 self.members.append(IdlDictionaryMember(idl_name, child))
223 elif child_class == 'ExtAttributes':
224 self.extended_attributes = (
225 ext_attributes_node_to_extended_attributes(idl_name, child))
226 else:
227 raise ValueError('Unrecognized node class: %s' % child_class)
228
229
230 class IdlDictionaryMember(object):
231 def __init__(self, idl_name, node):
232 self.default_value = None
233 self.extended_attributes = {}
234 self.idl_type = None
235 self.idl_name = idl_name
236 self.name = node.GetName()
237 for child in node.GetChildren():
238 child_class = child.GetClass()
239 if child_class == 'Type':
240 self.idl_type = type_node_to_type(child)
241 elif child_class == 'Default':
242 self.default_value = default_node_to_idl_literal(child)
243 elif child_class == 'ExtAttributes':
244 self.extended_attributes = (
245 ext_attributes_node_to_extended_attributes(idl_name, child))
246 else:
247 raise ValueError('Unrecognized node class: %s' % child_class)
248
249
250 ################################################################################
251 # Enumerations
252 ################################################################################
253
254 class IdlEnum(object):
255 # FIXME: remove, just treat enums as a dictionary
256 def __init__(self, idl_name, node):
257 self.idl_name = idl_name
258 self.name = node.GetName()
259 self.values = []
260 for child in node.GetChildren():
261 self.values.append(child.GetName())
262
263
264 ################################################################################
265 # Interfaces and Exceptions
266 ################################################################################
267
268 class IdlInterface(object):
269 def __init__(self, idl_name, node=None):
270 self.attributes = []
271 self.constants = []
272 self.constructors = []
273 self.custom_constructors = []
274 self.extended_attributes = {}
275 self.operations = []
276 self.parent = None
277 self.stringifier = None
278 if not node: # Early exit for IdlException.__init__
279 return
280
281 self.is_callback = node.GetProperty('CALLBACK') or False
282 self.is_exception = False
283 # FIXME: uppercase 'Partial' => 'PARTIAL' in base IDL parser
284 self.is_partial = node.GetProperty('Partial') or False
285 self.idl_name = idl_name
286 self.name = node.GetName()
287
288 children = node.GetChildren()
289 for child in children:
290 child_class = child.GetClass()
291 if child_class == 'Attribute':
292 self.attributes.append(IdlAttribute(idl_name, child))
293 elif child_class == 'Const':
294 self.constants.append(IdlConstant(idl_name, child))
295 elif child_class == 'ExtAttributes':
296 extended_attributes = ext_attributes_node_to_extended_attributes (idl_name, child)
297 self.constructors, self.custom_constructors = (
298 extended_attributes_to_constructors(idl_name, extended_attri butes))
299 clear_constructor_attributes(extended_attributes)
300 self.extended_attributes = extended_attributes
301 elif child_class == 'Operation':
302 self.operations.append(IdlOperation(idl_name, child))
303 elif child_class == 'Inherit':
304 self.parent = child.GetName()
305 elif child_class == 'Stringifier':
306 self.stringifier = IdlStringifier(idl_name, child)
307 self.process_stringifier()
308 else:
309 raise ValueError('Unrecognized node class: %s' % child_class)
310
311 def resolve_typedefs(self, typedefs):
312 for attribute in self.attributes:
313 attribute.resolve_typedefs(typedefs)
314 for constant in self.constants:
315 constant.resolve_typedefs(typedefs)
316 for constructor in self.constructors:
317 constructor.resolve_typedefs(typedefs)
318 for custom_constructor in self.custom_constructors:
319 custom_constructor.resolve_typedefs(typedefs)
320 for operation in self.operations:
321 operation.resolve_typedefs(typedefs)
322
323 def process_stringifier(self):
324 """Add the stringifier's attribute or named operation child, if it has
325 one, as a regular attribute/operation of this interface."""
326 if self.stringifier.attribute:
327 self.attributes.append(self.stringifier.attribute)
328 elif self.stringifier.operation:
329 self.operations.append(self.stringifier.operation)
330
331 def merge(self, other):
332 """Merge in another interface's members (e.g., partial interface)"""
333 self.attributes.extend(other.attributes)
334 self.constants.extend(other.constants)
335 self.operations.extend(other.operations)
336
337
338 class IdlException(IdlInterface):
339 # Properly exceptions and interfaces are distinct, and thus should inherit a
340 # common base class (say, "IdlExceptionOrInterface").
341 # However, there is only one exception (DOMException), and new exceptions
342 # are not expected. Thus it is easier to implement exceptions as a
343 # restricted subclass of interfaces.
344 # http://www.w3.org/TR/WebIDL/#idl-exceptions
345 def __init__(self, idl_name, node):
346 # Exceptions are similar to Interfaces, but simpler
347 IdlInterface.__init__(self, idl_name)
348 self.is_callback = False
349 self.is_exception = True
350 self.is_partial = False
351 self.idl_name = idl_name
352 self.name = node.GetName()
353
354 children = node.GetChildren()
355 for child in children:
356 child_class = child.GetClass()
357 if child_class == 'Attribute':
358 attribute = IdlAttribute(idl_name, child)
359 self.attributes.append(attribute)
360 elif child_class == 'Const':
361 self.constants.append(IdlConstant(idl_name, child))
362 elif child_class == 'ExtAttributes':
363 self.extended_attributes = ext_attributes_node_to_extended_attri butes(idl_name, child)
364 elif child_class == 'ExceptionOperation':
365 self.operations.append(IdlOperation.from_exception_operation_nod e(idl_name, child))
366 else:
367 raise ValueError('Unrecognized node class: %s' % child_class)
368
369
370 ################################################################################
371 # Attributes
372 ################################################################################
373
374 class IdlAttribute(TypedObject):
375 def __init__(self, idl_name, node):
376 self.is_read_only = node.GetProperty('READONLY') or False
377 self.is_static = node.GetProperty('STATIC') or False
378 self.idl_name = idl_name
379 self.name = node.GetName()
380 # Defaults, overridden below
381 self.idl_type = None
382 self.extended_attributes = {}
383
384 children = node.GetChildren()
385 for child in children:
386 child_class = child.GetClass()
387 if child_class == 'Type':
388 self.idl_type = type_node_to_type(child)
389 elif child_class == 'ExtAttributes':
390 self.extended_attributes = ext_attributes_node_to_extended_attri butes(idl_name, child)
391 else:
392 raise ValueError('Unrecognized node class: %s' % child_class)
393
394
395 ################################################################################
396 # Constants
397 ################################################################################
398
399 class IdlConstant(TypedObject):
400 def __init__(self, idl_name, node):
401 children = node.GetChildren()
402 num_children = len(children)
403 if num_children < 2 or num_children > 3:
404 raise ValueError('Expected 2 or 3 children, got %s' % num_children)
405 type_node = children[0]
406 value_node = children[1]
407 value_node_class = value_node.GetClass()
408 if value_node_class != 'Value':
409 raise ValueError('Expected Value node, got %s' % value_node_class)
410
411 self.idl_name = idl_name
412 self.name = node.GetName()
413 # ConstType is more limited than Type, so subtree is smaller and
414 # we don't use the full type_node_to_type function.
415 self.idl_type = type_node_inner_to_type(type_node)
416 # FIXME: This code is unnecessarily complicated due to the rather
417 # inconsistent way the upstream IDL parser outputs default values.
418 # http://crbug.com/374178
419 if value_node.GetProperty('TYPE') == 'float':
420 self.value = value_node.GetProperty('VALUE')
421 else:
422 self.value = value_node.GetName()
423
424 if num_children == 3:
425 ext_attributes_node = children[2]
426 self.extended_attributes = ext_attributes_node_to_extended_attribute s(idl_name, ext_attributes_node)
427 else:
428 self.extended_attributes = {}
429
430
431 ################################################################################
432 # Literals
433 ################################################################################
434
435 class IdlLiteral(object):
436 def __init__(self, idl_type, value):
437 self.idl_type = idl_type
438 self.value = value
439 self.is_null = False
440
441 def __str__(self):
442 if self.idl_type == 'DOMString':
443 return 'String("%s")' % self.value
444 if self.idl_type == 'integer':
445 return '%d' % self.value
446 if self.idl_type == 'float':
447 return '%g' % self.value
448 if self.idl_type == 'boolean':
449 return 'true' if self.value else 'false'
450 raise ValueError('Unsupported literal type: %s' % self.idl_type)
451
452
453 class IdlLiteralNull(IdlLiteral):
454 def __init__(self):
455 self.idl_type = 'NULL'
456 self.value = None
457 self.is_null = True
458
459 def __str__(self):
460 return 'nullptr'
461
462
463 def default_node_to_idl_literal(node):
464 # FIXME: This code is unnecessarily complicated due to the rather
465 # inconsistent way the upstream IDL parser outputs default values.
466 # http://crbug.com/374178
467 idl_type = node.GetProperty('TYPE')
468 if idl_type == 'DOMString':
469 value = node.GetProperty('NAME')
470 if '"' in value or '\\' in value:
471 raise ValueError('Unsupported string value: %r' % value)
472 return IdlLiteral(idl_type, value)
473 if idl_type == 'integer':
474 return IdlLiteral(idl_type, int(node.GetProperty('NAME'), base=0))
475 if idl_type == 'float':
476 return IdlLiteral(idl_type, float(node.GetProperty('VALUE')))
477 if idl_type == 'boolean':
478 return IdlLiteral(idl_type, node.GetProperty('VALUE'))
479 if idl_type == 'NULL':
480 return IdlLiteralNull()
481 raise ValueError('Unrecognized default value type: %s' % idl_type)
482
483
484 ################################################################################
485 # Operations
486 ################################################################################
487
488 class IdlOperation(TypedObject):
489 def __init__(self, idl_name, node=None):
490 self.arguments = []
491 self.extended_attributes = {}
492 self.specials = []
493 self.is_constructor = False
494
495 if not node:
496 self.is_static = False
497 return
498 self.idl_name = idl_name
499 self.name = node.GetName() # FIXME: should just be: or ''
500 # FIXME: AST should use None internally
501 if self.name == '_unnamed_':
502 self.name = ''
503
504 self.is_static = node.GetProperty('STATIC') or False
505 property_dictionary = node.GetProperties()
506 for special_keyword in SPECIAL_KEYWORD_LIST:
507 if special_keyword in property_dictionary:
508 self.specials.append(special_keyword.lower())
509
510 self.idl_type = None
511 children = node.GetChildren()
512 for child in children:
513 child_class = child.GetClass()
514 if child_class == 'Arguments':
515 self.arguments = arguments_node_to_arguments(idl_name, child)
516 elif child_class == 'Type':
517 self.idl_type = type_node_to_type(child)
518 elif child_class == 'ExtAttributes':
519 self.extended_attributes = ext_attributes_node_to_extended_attri butes(idl_name, child)
520 else:
521 raise ValueError('Unrecognized node class: %s' % child_class)
522
523 @classmethod
524 def from_exception_operation_node(cls, idl_name, node):
525 # Needed to handle one case in DOMException.idl:
526 # // Override in a Mozilla compatible format
527 # [NotEnumerable] DOMString toString();
528 # FIXME: can we remove this? replace with a stringifier?
529 operation = cls(idl_name)
530 operation.name = node.GetName()
531 children = node.GetChildren()
532 if len(children) < 1 or len(children) > 2:
533 raise ValueError('ExceptionOperation node with %s children, expected 1 or 2' % len(children))
534
535 type_node = children[0]
536 operation.idl_type = type_node_to_type(type_node)
537
538 if len(children) > 1:
539 ext_attributes_node = children[1]
540 operation.extended_attributes = ext_attributes_node_to_extended_attr ibutes(idl_name, ext_attributes_node)
541
542 return operation
543
544 @classmethod
545 def constructor_from_arguments_node(cls, name, idl_name, arguments_node):
546 constructor = cls(idl_name)
547 constructor.name = name
548 constructor.arguments = arguments_node_to_arguments(idl_name, arguments_ node)
549 constructor.is_constructor = True
550 return constructor
551
552 def resolve_typedefs(self, typedefs):
553 TypedObject.resolve_typedefs(self, typedefs)
554 for argument in self.arguments:
555 argument.resolve_typedefs(typedefs)
556
557
558 ################################################################################
559 # Arguments
560 ################################################################################
561
562 class IdlArgument(TypedObject):
563 def __init__(self, idl_name, node):
564 self.extended_attributes = {}
565 self.idl_type = None
566 self.is_optional = node.GetProperty('OPTIONAL') # syntax: (optional T)
567 self.is_variadic = False # syntax: (T...)
568 self.idl_name = idl_name
569 self.name = node.GetName()
570 self.default_value = None
571
572 children = node.GetChildren()
573 for child in children:
574 child_class = child.GetClass()
575 if child_class == 'Type':
576 self.idl_type = type_node_to_type(child)
577 elif child_class == 'ExtAttributes':
578 self.extended_attributes = ext_attributes_node_to_extended_attri butes(idl_name, child)
579 elif child_class == 'Argument':
580 child_name = child.GetName()
581 if child_name != '...':
582 raise ValueError('Unrecognized Argument node; expected "..." , got "%s"' % child_name)
583 self.is_variadic = child.GetProperty('ELLIPSIS') or False
584 elif child_class == 'Default':
585 self.default_value = default_node_to_idl_literal(child)
586 else:
587 raise ValueError('Unrecognized node class: %s' % child_class)
588
589
590 def arguments_node_to_arguments(idl_name, node):
591 # [Constructor] and [CustomConstructor] without arguments (the bare form)
592 # have None instead of an arguments node, but have the same meaning as using
593 # an empty argument list, [Constructor()], so special-case this.
594 # http://www.w3.org/TR/WebIDL/#Constructor
595 if node is None:
596 return []
597 return [IdlArgument(idl_name, argument_node)
598 for argument_node in node.GetChildren()]
599
600
601 ################################################################################
602 # Stringifiers
603 ################################################################################
604
605 class IdlStringifier(object):
606 def __init__(self, idl_name, node):
607 self.attribute = None
608 self.operation = None
609 self.extended_attributes = {}
610 self.idl_name = idl_name
611
612 for child in node.GetChildren():
613 child_class = child.GetClass()
614 if child_class == 'Attribute':
615 self.attribute = IdlAttribute(idl_name, child)
616 elif child_class == 'Operation':
617 operation = IdlOperation(idl_name, child)
618 if operation.name:
619 self.operation = operation
620 elif child_class == 'ExtAttributes':
621 self.extended_attributes = ext_attributes_node_to_extended_attri butes(idl_name, child)
622 else:
623 raise ValueError('Unrecognized node class: %s' % child_class)
624
625 # Copy the stringifier's extended attributes (such as [Unforgable]) onto
626 # the underlying attribute or operation, if there is one.
627 if self.attribute or self.operation:
628 (self.attribute or self.operation).extended_attributes.update(
629 self.extended_attributes)
630
631
632 ################################################################################
633 # Extended attributes
634 ################################################################################
635
636 def ext_attributes_node_to_extended_attributes(idl_name, node):
637 """
638 Returns:
639 Dictionary of {ExtAttributeName: ExtAttributeValue}.
640 Value is usually a string, with these exceptions:
641 Constructors: value is a list of Arguments nodes, corresponding to
642 possible signatures of the constructor.
643 CustomConstructors: value is a list of Arguments nodes, corresponding to
644 possible signatures of the custom constructor.
645 NamedConstructor: value is a Call node, corresponding to the single
646 signature of the named constructor.
647 SetWrapperReferenceTo: value is an Arguments node.
648 """
649 # Primarily just make a dictionary from the children.
650 # The only complexity is handling various types of constructors:
651 # Constructors and Custom Constructors can have duplicate entries due to
652 # overloading, and thus are stored in temporary lists.
653 # However, Named Constructors cannot be overloaded, and thus do not have
654 # a list.
655 # FIXME: move Constructor logic into separate function, instead of modifying
656 # extended attributes in-place.
657 constructors = []
658 custom_constructors = []
659 extended_attributes = {}
660
661 def child_node(extended_attribute_node):
662 children = extended_attribute_node.GetChildren()
663 if not children:
664 return None
665 if len(children) > 1:
666 raise ValueError('ExtAttributes node with %s children, expected at m ost 1' % len(children))
667 return children[0]
668
669 extended_attribute_node_list = node.GetChildren()
670 for extended_attribute_node in extended_attribute_node_list:
671 name = extended_attribute_node.GetName()
672 child = child_node(extended_attribute_node)
673 child_class = child and child.GetClass()
674 if name == 'Constructor':
675 if child_class and child_class != 'Arguments':
676 raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class)
677 constructors.append(child)
678 elif name == 'CustomConstructor':
679 if child_class and child_class != 'Arguments':
680 raise ValueError('[CustomConstructor] only supports Arguments as child, but has child of class: %s' % child_class)
681 custom_constructors.append(child)
682 elif name == 'NamedConstructor':
683 if child_class and child_class != 'Call':
684 raise ValueError('[NamedConstructor] only supports Call as child , but has child of class: %s' % child_class)
685 extended_attributes[name] = child
686 elif name == 'SetWrapperReferenceTo':
687 if not child:
688 raise ValueError('[SetWrapperReferenceTo] requires a child, but has none.')
689 if child_class != 'Arguments':
690 raise ValueError('[SetWrapperReferenceTo] only supports Argument s as child, but has child of class: %s' % child_class)
691 extended_attributes[name] = arguments_node_to_arguments(idl_name, ch ild)
692 elif child:
693 raise ValueError('ExtAttributes node with unexpected children: %s' % name)
694 else:
695 value = extended_attribute_node.GetProperty('VALUE')
696 extended_attributes[name] = value
697
698 # Store constructors and custom constructors in special list attributes,
699 # which are deleted later. Note plural in key.
700 if constructors:
701 extended_attributes['Constructors'] = constructors
702 if custom_constructors:
703 extended_attributes['CustomConstructors'] = custom_constructors
704
705 return extended_attributes
706
707
708 def extended_attributes_to_constructors(idl_name, extended_attributes):
709 """Returns constructors and custom_constructors (lists of IdlOperations).
710
711 Auxiliary function for IdlInterface.__init__.
712 """
713
714 constructor_list = extended_attributes.get('Constructors', [])
715 constructors = [
716 IdlOperation.constructor_from_arguments_node('Constructor', idl_name, ar guments_node)
717 for arguments_node in constructor_list]
718
719 custom_constructor_list = extended_attributes.get('CustomConstructors', [])
720 custom_constructors = [
721 IdlOperation.constructor_from_arguments_node('CustomConstructor', idl_na me, arguments_node)
722 for arguments_node in custom_constructor_list]
723
724 if 'NamedConstructor' in extended_attributes:
725 # FIXME: support overloaded named constructors, and make homogeneous
726 name = 'NamedConstructor'
727 call_node = extended_attributes['NamedConstructor']
728 extended_attributes['NamedConstructor'] = call_node.GetName()
729 children = call_node.GetChildren()
730 if len(children) != 1:
731 raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children))
732 arguments_node = children[0]
733 named_constructor = IdlOperation.constructor_from_arguments_node('NamedC onstructor', idl_name, arguments_node)
734 # FIXME: should return named_constructor separately; appended for Perl
735 constructors.append(named_constructor)
736
737 return constructors, custom_constructors
738
739
740 def clear_constructor_attributes(extended_attributes):
741 # Deletes Constructor*s* (plural), sets Constructor (singular)
742 if 'Constructors' in extended_attributes:
743 del extended_attributes['Constructors']
744 extended_attributes['Constructor'] = None
745 if 'CustomConstructors' in extended_attributes:
746 del extended_attributes['CustomConstructors']
747 extended_attributes['CustomConstructor'] = None
748
749
750 ################################################################################
751 # Types
752 ################################################################################
753
754 def type_node_to_type(node):
755 children = node.GetChildren()
756 if len(children) < 1 or len(children) > 2:
757 raise ValueError('Type node expects 1 or 2 children (type + optional arr ay []), got %s (multi-dimensional arrays are not supported).' % len(children))
758
759 base_type = type_node_inner_to_type(children[0])
760
761 if node.GetProperty('NULLABLE'):
762 base_type = IdlNullableType(base_type)
763
764 if len(children) == 2:
765 array_node = children[1]
766 array_node_class = array_node.GetClass()
767 if array_node_class != 'Array':
768 raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class)
769 array_type = IdlArrayType(base_type)
770 if array_node.GetProperty('NULLABLE'):
771 return IdlNullableType(array_type)
772 return array_type
773
774 return base_type
775
776
777 def type_node_inner_to_type(node):
778 node_class = node.GetClass()
779 # Note Type*r*ef, not Typedef, meaning the type is an identifier, thus
780 # either a typedef shorthand (but not a Typedef declaration itself) or an
781 # interface type. We do not distinguish these, and just use the type name.
782 if node_class in ['PrimitiveType', 'Typeref']:
783 # unrestricted syntax: unrestricted double | unrestricted float
784 is_unrestricted = node.GetProperty('UNRESTRICTED') or False
785 return IdlType(node.GetName(), is_unrestricted=is_unrestricted)
786 elif node_class == 'Any':
787 return IdlType('any')
788 elif node_class == 'Sequence':
789 return sequence_node_to_type(node)
790 elif node_class == 'UnionType':
791 return union_type_node_to_idl_union_type(node)
792 elif node_class == 'Promise':
793 return IdlType('Promise')
794 raise ValueError('Unrecognized node class: %s' % node_class)
795
796
797 def sequence_node_to_type(node):
798 children = node.GetChildren()
799 if len(children) != 1:
800 raise ValueError('Sequence node expects exactly 1 child, got %s' % len(c hildren))
801 sequence_child = children[0]
802 sequence_child_class = sequence_child.GetClass()
803 if sequence_child_class != 'Type':
804 raise ValueError('Unrecognized node class: %s' % sequence_child_class)
805 element_type = type_node_to_type(sequence_child)
806 sequence_type = IdlSequenceType(element_type)
807 if node.GetProperty('NULLABLE'):
808 return IdlNullableType(sequence_type)
809 return sequence_type
810
811
812 def typedef_node_to_type(node):
813 children = node.GetChildren()
814 if len(children) != 1:
815 raise ValueError('Typedef node with %s children, expected 1' % len(child ren))
816 child = children[0]
817 child_class = child.GetClass()
818 if child_class != 'Type':
819 raise ValueError('Unrecognized node class: %s' % child_class)
820 return type_node_to_type(child)
821
822
823 def union_type_node_to_idl_union_type(node):
824 member_types = [type_node_to_type(member_type_node)
825 for member_type_node in node.GetChildren()]
826 return IdlUnionType(member_types)
OLDNEW
« no previous file with comments | « sky/engine/bindings/scripts/idl_compiler.py ('k') | sky/engine/bindings/scripts/idl_reader.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698