Upstream version 6.35.121.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 IdlType
8 IdlUnionType
9 """
10
11 from collections import defaultdict
12
13
14 ################################################################################
15 # IDL types
16 ################################################################################
17
18 BASIC_TYPES = set([
19     # Built-in, non-composite, non-object data types
20     # http://www.w3.org/TR/WebIDL/#dfn-primitive-type
21     'boolean',
22     'float',
23     # unrestricted float is not supported
24     'double',
25     # unrestricted double is not supported
26     # http://www.w3.org/TR/WebIDL/#idl-types
27     'DOMString',
28     'Date',
29     # http://www.w3.org/TR/WebIDL/#es-type-mapping
30     'void',
31 ])
32 INTEGER_TYPES = frozenset([
33     # http://www.w3.org/TR/WebIDL/#dfn-integer-type
34     'byte',
35     'octet',
36     'short',
37     'unsigned short',
38     # int and unsigned are not IDL types
39     'long',
40     'unsigned long',
41     'long long',
42     'unsigned long long',
43 ])
44 BASIC_TYPES.update(INTEGER_TYPES)
45 TYPE_NAMES = {
46     # http://heycam.github.io/webidl/#dfn-type-name
47     'any': 'Any',
48     'boolean': 'Boolean',
49     'byte': 'Byte',
50     'octet': 'Octet',
51     'short': 'Short',
52     'unsigned short': 'UnsignedShort',
53     'long': 'Long',
54     'unsigned long': 'UnsignedLong',
55     'long long': 'LongLong',
56     'unsigned long long': 'UnsignedLongLong',
57     'float': 'Float',
58     'unrestricted float': 'UnrestrictedFloat',
59     'double': 'Double',
60     'unrestricted double': 'UnrestrictedDouble',
61     'DOMString': 'String',
62     'ByteString': 'ByteString',
63     'object': 'Object',
64 }
65
66
67 ################################################################################
68 # Inheritance
69 ################################################################################
70
71 ancestors = defaultdict(list)  # interface_name -> ancestors
72
73 def inherits_interface(interface_name, ancestor_name):
74     return (interface_name == ancestor_name or
75             ancestor_name in ancestors[interface_name])
76
77
78 def set_ancestors(new_ancestors):
79     ancestors.update(new_ancestors)
80
81
82 ################################################################################
83 # IdlType
84 ################################################################################
85
86 class IdlType(object):
87     # FIXME: incorporate Nullable, etc.
88     # FIXME: use nested types: IdlArrayType, IdlNullableType, IdlSequenceType
89     # to support types like short?[] vs. short[]?, instead of treating these
90     # as orthogonal properties (via flags).
91     callback_functions = set()
92     callback_interfaces = set()
93     enums = {}  # name -> values
94
95     def __init__(self, base_type, is_array=False, is_sequence=False, is_nullable=False):
96         if is_array and is_sequence:
97             raise ValueError('Array of Sequences are not allowed.')
98         self.base_type = base_type
99         self.is_array = is_array
100         self.is_sequence = is_sequence
101         self.is_nullable = is_nullable
102
103     def __str__(self):
104         type_string = self.base_type
105         if self.is_array:
106             return type_string + '[]'
107         if self.is_sequence:
108             return 'sequence<%s>' % type_string
109         if self.is_nullable:
110             # FIXME: Dictionary::ConversionContext::setConversionType can't
111             # handle the '?' in nullable types (passes nullability separately).
112             # Update that function to handle nullability from the type name,
113             # simplifying its signature.
114             # return type_string + '?'
115             return type_string
116         return type_string
117
118     # FIXME: rename to native_array_element_type and move to v8_types.py
119     @property
120     def array_or_sequence_type(self):
121         return self.array_type or self.sequence_type
122
123     # FIXME: rename to array_element_type
124     @property
125     def array_type(self):
126         return self.is_array and IdlType(self.base_type)
127
128     # FIXME: rename to sequence_element_type
129     @property
130     def sequence_type(self):
131         return self.is_sequence and IdlType(self.base_type)
132
133     @property
134     def is_basic_type(self):
135         return self.base_type in BASIC_TYPES and not self.array_or_sequence_type
136
137     @property
138     def is_callback_function(self):
139         return self.base_type in IdlType.callback_functions
140
141     @property
142     def is_callback_interface(self):
143         return self.base_type in IdlType.callback_interfaces
144
145     @property
146     def is_composite_type(self):
147         return (self.name == 'Any' or
148                 self.array_type or
149                 self.sequence_type or
150                 self.is_union_type)
151
152     @property
153     def is_enum(self):
154         # FIXME: add an IdlEnumType class and a resolve_enums step at end of
155         # IdlDefinitions constructor
156         return self.name in IdlType.enums
157
158     @property
159     def enum_values(self):
160         return IdlType.enums[self.name]
161
162     @property
163     def is_integer_type(self):
164         return self.base_type in INTEGER_TYPES and not self.array_or_sequence_type
165
166     @property
167     def is_interface_type(self):
168         # Anything that is not another type is an interface type.
169         # http://www.w3.org/TR/WebIDL/#idl-types
170         # http://www.w3.org/TR/WebIDL/#idl-interface
171         # In C++ these are RefPtr or PassRefPtr types.
172         return not(self.is_basic_type or
173                    self.is_composite_type or
174                    self.is_callback_function or
175                    self.is_enum or
176                    self.name == 'Object' or
177                    self.name == 'Promise')  # Promise will be basic in future
178
179     @property
180     def is_union_type(self):
181         return isinstance(self, IdlUnionType)
182
183     @property
184     def name(self):
185         """Return type name.
186
187         http://heycam.github.io/webidl/#dfn-type-name
188         """
189         base_type = self.base_type
190         base_type_name = TYPE_NAMES.get(base_type, base_type)
191         if self.is_array:
192             return base_type_name + 'Array'
193         if self.is_sequence:
194             return base_type_name + 'Sequence'
195         if self.is_nullable:
196             return base_type_name + 'OrNull'
197         return base_type_name
198
199     @classmethod
200     def set_callback_functions(cls, new_callback_functions):
201         cls.callback_functions.update(new_callback_functions)
202
203     @classmethod
204     def set_callback_interfaces(cls, new_callback_interfaces):
205         cls.callback_interfaces.update(new_callback_interfaces)
206
207     @classmethod
208     def set_enums(cls, new_enums):
209         cls.enums.update(new_enums)
210
211     def resolve_typedefs(self, typedefs):
212         if self.base_type not in typedefs:
213             return self
214         new_type = typedefs[self.base_type]
215         if type(new_type) != type(self):
216             # If type changes, need to return a different object,
217             # since can't change type(self)
218             return new_type
219         # If type doesn't change, just mutate self to avoid a new object
220         # FIXME: a bit ugly; use __init__ instead of setting flags
221         self.base_type = new_type.base_type
222         # handle array both in use and in typedef itself:
223         # typedef Type TypeDef;
224         # TypeDef[] ...
225         # and:
226         # typedef Type[] TypeArray
227         # TypeArray ...
228         self.is_array |= new_type.is_array
229         self.is_sequence |= new_type.is_sequence
230         return self
231
232
233 ################################################################################
234 # IdlUnionType
235 ################################################################################
236
237 class IdlUnionType(object):
238     # http://heycam.github.io/webidl/#idl-union
239     # FIXME: derive from IdlType, instead of stand-alone class, to reduce
240     # duplication.
241     def __init__(self, member_types, is_nullable=False):
242         self.member_types = member_types
243         self.is_nullable = is_nullable
244
245     @property
246     def array_or_sequence_type(self):
247         return False
248
249     @property
250     def array_type(self):
251         return False
252
253     @property
254     def is_array(self):
255         # We do not support arrays of union types
256         return False
257
258     @property
259     def base_type(self):
260         return None
261
262     @property
263     def is_basic_type(self):
264         return False
265
266     @property
267     def is_callback_function(self):
268         return False
269
270     @property
271     def is_enum(self):
272         return False
273
274     @property
275     def is_integer_type(self):
276         return False
277
278     @property
279     def is_sequence(self):
280         # We do not support sequences of union types
281         return False
282
283     @property
284     def is_union_type(self):
285         return True
286
287     @property
288     def name(self):
289         return 'Or'.join(member_type.name for member_type in self.member_types)
290
291     def resolve_typedefs(self, typedefs):
292         self.member_types = [
293             typedefs.get(member_type, member_type)
294             for member_type in self.member_types]
295         return self