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.
10 IdlArrayOrSequenceType
16 from collections import defaultdict
19 ################################################################################
21 ################################################################################
23 INTEGER_TYPES = frozenset([
24 # http://www.w3.org/TR/WebIDL/#dfn-integer-type
29 # int and unsigned are not IDL types
35 NUMERIC_TYPES = (INTEGER_TYPES | frozenset([
36 # http://www.w3.org/TR/WebIDL/#dfn-numeric-type
40 'unrestricted double',
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
50 # http://heycam.github.io/webidl/#es-type-mapping
52 # http://encoding.spec.whatwg.org/#type-scalarvaluestring
56 # http://heycam.github.io/webidl/#dfn-type-name
62 'unsigned short': 'UnsignedShort',
64 'unsigned long': 'UnsignedLong',
65 'long long': 'LongLong',
66 'unsigned long long': 'UnsignedLongLong',
68 'unrestricted float': 'UnrestrictedFloat',
70 'unrestricted double': 'UnrestrictedDouble',
71 'DOMString': 'String',
72 'ByteString': 'ByteString',
73 'ScalarValueString': 'ScalarValueString',
78 STRING_TYPES = frozenset([
79 # http://heycam.github.io/webidl/#es-interface-call (step 10.11)
80 # (Interface object [[Call]] method's string types.)
87 ################################################################################
89 ################################################################################
91 ancestors = defaultdict(list) # interface_name -> ancestors
93 def inherits_interface(interface_name, ancestor_name):
94 return (interface_name == ancestor_name or
95 ancestor_name in ancestors[interface_name])
98 def set_ancestors(new_ancestors):
99 ancestors.update(new_ancestors)
102 class IdlTypeBase(object):
103 """Base class for IdlType, IdlUnionType, IdlArrayOrSequenceType and IdlNullableType."""
106 raise NotImplementedError(
107 '__str__() should be defined in subclasses')
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.
115 def resolve_typedefs(self, typedefs):
116 raise NotImplementedError(
117 'resolve_typedefs should be defined in subclasses')
120 ################################################################################
122 ################################################################################
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()
131 enums = {} # name -> values
133 def __init__(self, base_type, is_unrestricted=False):
134 super(IdlType, self).__init__()
136 self.base_type = 'unrestricted %s' % base_type
138 self.base_type = base_type
141 return self.base_type
144 def is_basic_type(self):
145 return self.base_type in BASIC_TYPES
148 def is_callback_function(self):
149 return self.base_type in IdlType.callback_functions
152 def is_callback_interface(self):
153 return self.base_type in IdlType.callback_interfaces
156 def is_dictionary(self):
157 return self.base_type in IdlType.dictionaries
161 # FIXME: add an IdlEnumType class and a resolve_enums step at end of
162 # IdlDefinitions constructor
163 return self.name in IdlType.enums
166 def enum_values(self):
167 return IdlType.enums[self.name]
170 def is_integer_type(self):
171 return self.base_type in INTEGER_TYPES
174 def is_numeric_type(self):
175 return self.base_type in NUMERIC_TYPES
178 def is_primitive_type(self):
179 return self.base_type in PRIMITIVE_TYPES
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
191 self.name == 'Any' or
192 self.name == 'Object' or
193 self.name == 'Promise') # Promise will be basic in future
196 def is_string_type(self):
197 return self.name in STRING_TYPES
200 def is_union_type(self):
201 return isinstance(self, IdlUnionType)
207 http://heycam.github.io/webidl/#dfn-type-name
209 base_type = self.base_type
210 return TYPE_NAMES.get(base_type, base_type)
213 def set_callback_functions(cls, new_callback_functions):
214 cls.callback_functions.update(new_callback_functions)
217 def set_callback_interfaces(cls, new_callback_interfaces):
218 cls.callback_interfaces.update(new_callback_interfaces)
221 def set_dictionaries(cls, new_dictionaries):
222 cls.dictionaries.update(new_dictionaries)
225 def set_enums(cls, new_enums):
226 cls.enums.update(new_enums)
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)
234 ################################################################################
236 ################################################################################
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
245 def is_union_type(self):
250 """Return type name (or inner type name if nullable)
252 http://heycam.github.io/webidl/#dfn-type-name
254 return 'Or'.join(member_type.name for member_type in self.member_types)
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]
263 ################################################################################
264 # IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType
265 ################################################################################
267 class IdlArrayOrSequenceType(IdlTypeBase):
268 """Base class for IdlArrayType and IdlSequenceType."""
270 def __init__(self, element_type):
271 super(IdlArrayOrSequenceType, self).__init__()
272 self.element_type = element_type
274 def resolve_typedefs(self, typedefs):
275 self.element_type = self.element_type.resolve_typedefs(typedefs)
279 class IdlArrayType(IdlArrayOrSequenceType):
280 def __init__(self, element_type):
281 super(IdlArrayType, self).__init__(element_type)
284 return '%s[]' % self.element_type
288 return self.element_type.name + 'Array'
291 class IdlSequenceType(IdlArrayOrSequenceType):
292 def __init__(self, element_type):
293 super(IdlSequenceType, self).__init__(element_type)
296 return 'sequence<%s>' % self.element_type
300 return self.element_type.name + 'Sequence'
303 ################################################################################
305 ################################################################################
307 class IdlNullableType(IdlTypeBase):
308 def __init__(self, inner_type):
309 super(IdlNullableType, self).__init__()
310 self.inner_type = inner_type
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)
320 def __getattr__(self, name):
321 return getattr(self.inner_type, name)
324 def is_nullable(self):
329 return self.inner_type.name + 'OrNull'
331 def resolve_typedefs(self, typedefs):
332 self.inner_type = self.inner_type.resolve_typedefs(typedefs)