Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / scripts / idl_types.py
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 """IDL type handling.
5
6 Classes:
7 IdlTypeBase
8  IdlType
9  IdlUnionType
10  IdlArrayOrSequenceType
11   IdlArrayType
12   IdlSequenceType
13  IdlNullableType
14 """
15
16 from collections import defaultdict
17
18
19 ################################################################################
20 # IDL types
21 ################################################################################
22
23 INTEGER_TYPES = frozenset([
24     # http://www.w3.org/TR/WebIDL/#dfn-integer-type
25     'byte',
26     'octet',
27     'short',
28     'unsigned short',
29     # int and unsigned are not IDL types
30     'long',
31     'unsigned long',
32     'long long',
33     'unsigned long long',
34 ])
35 NUMERIC_TYPES = (INTEGER_TYPES | frozenset([
36     # http://www.w3.org/TR/WebIDL/#dfn-numeric-type
37     'float',
38     'unrestricted float',
39     'double',
40     'unrestricted double',
41 ]))
42 # http://www.w3.org/TR/WebIDL/#dfn-primitive-type
43 PRIMITIVE_TYPES = (frozenset(['boolean']) | NUMERIC_TYPES)
44 BASIC_TYPES = (PRIMITIVE_TYPES | frozenset([
45     # Built-in, non-composite, non-object data types
46     # http://heycam.github.io/webidl/#idl-types
47     'DOMString',
48     'ByteString',
49     'Date',
50     # http://heycam.github.io/webidl/#es-type-mapping
51     'void',
52     # http://encoding.spec.whatwg.org/#type-scalarvaluestring
53     'ScalarValueString',
54 ]))
55 TYPE_NAMES = {
56     # http://heycam.github.io/webidl/#dfn-type-name
57     'any': 'Any',
58     'boolean': 'Boolean',
59     'byte': 'Byte',
60     'octet': 'Octet',
61     'short': 'Short',
62     'unsigned short': 'UnsignedShort',
63     'long': 'Long',
64     'unsigned long': 'UnsignedLong',
65     'long long': 'LongLong',
66     'unsigned long long': 'UnsignedLongLong',
67     'float': 'Float',
68     'unrestricted float': 'UnrestrictedFloat',
69     'double': 'Double',
70     'unrestricted double': 'UnrestrictedDouble',
71     'DOMString': 'String',
72     'ByteString': 'ByteString',
73     'ScalarValueString': 'ScalarValueString',
74     'object': 'Object',
75     'Date': 'Date',
76 }
77
78 STRING_TYPES = frozenset([
79     # http://heycam.github.io/webidl/#es-interface-call (step 10.11)
80     # (Interface object [[Call]] method's string types.)
81     'String',
82     'ByteString',
83     'ScalarValueString',
84 ])
85
86
87 ################################################################################
88 # Inheritance
89 ################################################################################
90
91 ancestors = defaultdict(list)  # interface_name -> ancestors
92
93 def inherits_interface(interface_name, ancestor_name):
94     return (interface_name == ancestor_name or
95             ancestor_name in ancestors[interface_name])
96
97
98 def set_ancestors(new_ancestors):
99     ancestors.update(new_ancestors)
100
101
102 class IdlTypeBase(object):
103     """Base class for IdlType, IdlUnionType, IdlArrayOrSequenceType and IdlNullableType."""
104
105     def __str__(self):
106         raise NotImplementedError(
107             '__str__() should be defined in subclasses')
108
109     def __getattr__(self, name):
110         # Default undefined attributes to None (analogous to Jinja variables).
111         # This allows us to not define default properties in the base class, and
112         # allows us to relay __getattr__ in IdlNullableType to the inner type.
113         return None
114
115     def resolve_typedefs(self, typedefs):
116         raise NotImplementedError(
117             'resolve_typedefs should be defined in subclasses')
118
119
120 ################################################################################
121 # IdlType
122 ################################################################################
123
124 class IdlType(IdlTypeBase):
125     # FIXME: incorporate Nullable, etc.
126     # to support types like short?[] vs. short[]?, instead of treating these
127     # as orthogonal properties (via flags).
128     callback_functions = set()
129     callback_interfaces = set()
130     dictionaries = set()
131     enums = {}  # name -> values
132
133     def __init__(self, base_type, is_unrestricted=False):
134         super(IdlType, self).__init__()
135         if is_unrestricted:
136             self.base_type = 'unrestricted %s' % base_type
137         else:
138             self.base_type = base_type
139
140     def __str__(self):
141         return self.base_type
142
143     @property
144     def is_basic_type(self):
145         return self.base_type in BASIC_TYPES
146
147     @property
148     def is_callback_function(self):
149         return self.base_type in IdlType.callback_functions
150
151     @property
152     def is_callback_interface(self):
153         return self.base_type in IdlType.callback_interfaces
154
155     @property
156     def is_dictionary(self):
157         return self.base_type in IdlType.dictionaries
158
159     @property
160     def is_enum(self):
161         # FIXME: add an IdlEnumType class and a resolve_enums step at end of
162         # IdlDefinitions constructor
163         return self.name in IdlType.enums
164
165     @property
166     def enum_values(self):
167         return IdlType.enums[self.name]
168
169     @property
170     def is_integer_type(self):
171         return self.base_type in INTEGER_TYPES
172
173     @property
174     def is_numeric_type(self):
175         return self.base_type in NUMERIC_TYPES
176
177     @property
178     def is_primitive_type(self):
179         return self.base_type in PRIMITIVE_TYPES
180
181     @property
182     def is_interface_type(self):
183         # Anything that is not another type is an interface type.
184         # http://www.w3.org/TR/WebIDL/#idl-types
185         # http://www.w3.org/TR/WebIDL/#idl-interface
186         # In C++ these are RefPtr or PassRefPtr types.
187         return not(self.is_basic_type or
188                    self.is_callback_function or
189                    self.is_dictionary or
190                    self.is_enum or
191                    self.name == 'Any' or
192                    self.name == 'Object' or
193                    self.name == 'Promise')  # Promise will be basic in future
194
195     @property
196     def is_string_type(self):
197         return self.name in STRING_TYPES
198
199     @property
200     def is_union_type(self):
201         return isinstance(self, IdlUnionType)
202
203     @property
204     def name(self):
205         """Return type name
206
207         http://heycam.github.io/webidl/#dfn-type-name
208         """
209         base_type = self.base_type
210         return TYPE_NAMES.get(base_type, base_type)
211
212     @classmethod
213     def set_callback_functions(cls, new_callback_functions):
214         cls.callback_functions.update(new_callback_functions)
215
216     @classmethod
217     def set_callback_interfaces(cls, new_callback_interfaces):
218         cls.callback_interfaces.update(new_callback_interfaces)
219
220     @classmethod
221     def set_dictionaries(cls, new_dictionaries):
222         cls.dictionaries.update(new_dictionaries)
223
224     @classmethod
225     def set_enums(cls, new_enums):
226         cls.enums.update(new_enums)
227
228     def resolve_typedefs(self, typedefs):
229         # This function either returns |self| or a different object.
230         # FIXME: Rename typedefs_resolved().
231         return typedefs.get(self.base_type, self)
232
233
234 ################################################################################
235 # IdlUnionType
236 ################################################################################
237
238 class IdlUnionType(IdlTypeBase):
239     # http://heycam.github.io/webidl/#idl-union
240     def __init__(self, member_types):
241         super(IdlUnionType, self).__init__()
242         self.member_types = member_types
243
244     @property
245     def is_union_type(self):
246         return True
247
248     @property
249     def name(self):
250         """Return type name (or inner type name if nullable)
251
252         http://heycam.github.io/webidl/#dfn-type-name
253         """
254         return 'Or'.join(member_type.name for member_type in self.member_types)
255
256     def resolve_typedefs(self, typedefs):
257         self.member_types = [
258             typedefs.get(member_type, member_type)
259             for member_type in self.member_types]
260         return self
261
262
263 ################################################################################
264 # IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType
265 ################################################################################
266
267 class IdlArrayOrSequenceType(IdlTypeBase):
268     """Base class for IdlArrayType and IdlSequenceType."""
269
270     def __init__(self, element_type):
271         super(IdlArrayOrSequenceType, self).__init__()
272         self.element_type = element_type
273
274     def resolve_typedefs(self, typedefs):
275         self.element_type = self.element_type.resolve_typedefs(typedefs)
276         return self
277
278
279 class IdlArrayType(IdlArrayOrSequenceType):
280     def __init__(self, element_type):
281         super(IdlArrayType, self).__init__(element_type)
282
283     def __str__(self):
284         return '%s[]' % self.element_type
285
286     @property
287     def name(self):
288         return self.element_type.name + 'Array'
289
290
291 class IdlSequenceType(IdlArrayOrSequenceType):
292     def __init__(self, element_type):
293         super(IdlSequenceType, self).__init__(element_type)
294
295     def __str__(self):
296         return 'sequence<%s>' % self.element_type
297
298     @property
299     def name(self):
300         return self.element_type.name + 'Sequence'
301
302
303 ################################################################################
304 # IdlNullableType
305 ################################################################################
306
307 class IdlNullableType(IdlTypeBase):
308     def __init__(self, inner_type):
309         super(IdlNullableType, self).__init__()
310         self.inner_type = inner_type
311
312     def __str__(self):
313         # FIXME: Dictionary::ConversionContext::setConversionType can't
314         # handle the '?' in nullable types (passes nullability separately).
315         # Update that function to handle nullability from the type name,
316         # simplifying its signature.
317         # return str(self.inner_type) + '?'
318         return str(self.inner_type)
319
320     def __getattr__(self, name):
321         return getattr(self.inner_type, name)
322
323     @property
324     def is_nullable(self):
325         return True
326
327     @property
328     def name(self):
329         return self.inner_type.name + 'OrNull'
330
331     def resolve_typedefs(self, typedefs):
332         self.inner_type = self.inner_type.resolve_typedefs(typedefs)
333         return self