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.
11 from collections import defaultdict
14 ################################################################################
16 ################################################################################
19 # Built-in, non-composite, non-object data types
20 # http://www.w3.org/TR/WebIDL/#dfn-primitive-type
23 # unrestricted float is not supported
25 # unrestricted double is not supported
26 # http://www.w3.org/TR/WebIDL/#idl-types
29 # http://www.w3.org/TR/WebIDL/#es-type-mapping
32 INTEGER_TYPES = frozenset([
33 # http://www.w3.org/TR/WebIDL/#dfn-integer-type
38 # int and unsigned are not IDL types
44 BASIC_TYPES.update(INTEGER_TYPES)
46 # http://heycam.github.io/webidl/#dfn-type-name
52 'unsigned short': 'UnsignedShort',
54 'unsigned long': 'UnsignedLong',
55 'long long': 'LongLong',
56 'unsigned long long': 'UnsignedLongLong',
58 'unrestricted float': 'UnrestrictedFloat',
60 'unrestricted double': 'UnrestrictedDouble',
61 'DOMString': 'String',
62 'ByteString': 'ByteString',
67 ################################################################################
69 ################################################################################
71 ancestors = defaultdict(list) # interface_name -> ancestors
73 def inherits_interface(interface_name, ancestor_name):
74 return (interface_name == ancestor_name or
75 ancestor_name in ancestors[interface_name])
78 def set_ancestors(new_ancestors):
79 ancestors.update(new_ancestors)
82 ################################################################################
84 ################################################################################
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
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
104 type_string = self.base_type
106 return type_string + '[]'
108 return 'sequence<%s>' % type_string
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 + '?'
118 # FIXME: rename to native_array_element_type and move to v8_types.py
120 def array_or_sequence_type(self):
121 return self.array_type or self.sequence_type
123 # FIXME: rename to array_element_type
125 def array_type(self):
126 return self.is_array and IdlType(self.base_type)
128 # FIXME: rename to sequence_element_type
130 def sequence_type(self):
131 return self.is_sequence and IdlType(self.base_type)
134 def is_basic_type(self):
135 return self.base_type in BASIC_TYPES and not self.array_or_sequence_type
138 def is_callback_function(self):
139 return self.base_type in IdlType.callback_functions
142 def is_callback_interface(self):
143 return self.base_type in IdlType.callback_interfaces
146 def is_composite_type(self):
147 return (self.name == 'Any' or
149 self.sequence_type or
154 # FIXME: add an IdlEnumType class and a resolve_enums step at end of
155 # IdlDefinitions constructor
156 return self.name in IdlType.enums
159 def enum_values(self):
160 return IdlType.enums[self.name]
163 def is_integer_type(self):
164 return self.base_type in INTEGER_TYPES and not self.array_or_sequence_type
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
176 self.name == 'Object' or
177 self.name == 'Promise') # Promise will be basic in future
180 def is_union_type(self):
181 return isinstance(self, IdlUnionType)
187 http://heycam.github.io/webidl/#dfn-type-name
189 base_type = self.base_type
190 base_type_name = TYPE_NAMES.get(base_type, base_type)
192 return base_type_name + 'Array'
194 return base_type_name + 'Sequence'
196 return base_type_name + 'OrNull'
197 return base_type_name
200 def set_callback_functions(cls, new_callback_functions):
201 cls.callback_functions.update(new_callback_functions)
204 def set_callback_interfaces(cls, new_callback_interfaces):
205 cls.callback_interfaces.update(new_callback_interfaces)
208 def set_enums(cls, new_enums):
209 cls.enums.update(new_enums)
211 def resolve_typedefs(self, typedefs):
212 if self.base_type not in typedefs:
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)
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;
226 # typedef Type[] TypeArray
228 self.is_array |= new_type.is_array
229 self.is_sequence |= new_type.is_sequence
233 ################################################################################
235 ################################################################################
237 class IdlUnionType(object):
238 # http://heycam.github.io/webidl/#idl-union
239 # FIXME: derive from IdlType, instead of stand-alone class, to reduce
241 def __init__(self, member_types, is_nullable=False):
242 self.member_types = member_types
243 self.is_nullable = is_nullable
246 def array_or_sequence_type(self):
250 def array_type(self):
255 # We do not support arrays of union types
263 def is_basic_type(self):
267 def is_callback_function(self):
275 def is_integer_type(self):
279 def is_sequence(self):
280 # We do not support sequences of union types
284 def is_union_type(self):
289 return 'Or'.join(member_type.name for member_type in self.member_types)
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]