Index: bindings/scripts/idl_types.py |
diff --git a/bindings/scripts/idl_types.py b/bindings/scripts/idl_types.py |
index e488e33264830157b37294bf42dd24c86ce5ac9d..d0797a67af79cbf2d393ccef906476e2fb923007 100644 |
--- a/bindings/scripts/idl_types.py |
+++ b/bindings/scripts/idl_types.py |
@@ -4,8 +4,12 @@ |
"""IDL type handling. |
Classes: |
-IdlType |
-IdlUnionType |
+IdlTypeBase |
+ IdlType |
+ IdlUnionType |
+ IdlArrayOrSequenceType |
+ IdlArrayType |
+ IdlSequenceType |
""" |
from collections import defaultdict |
@@ -70,6 +74,14 @@ TYPE_NAMES = { |
'Date': 'Date', |
} |
+STRING_TYPES = frozenset([ |
+ # http://heycam.github.io/webidl/#es-interface-call (step 10.11) |
+ # (Interface object [[Call]] method's string types.) |
+ 'String', |
+ 'ByteString', |
+ 'ScalarValueString', |
+]) |
+ |
################################################################################ |
# Inheritance |
@@ -86,63 +98,120 @@ def set_ancestors(new_ancestors): |
ancestors.update(new_ancestors) |
+class IdlTypeBase(object): |
+ """Base class for IdlType, IdlUnionType and IdlArrayOrSequenceType.""" |
+ |
+ def __init__(self, is_nullable): |
+ self.base_type = None |
+ self.is_nullable = is_nullable |
+ |
+ def __str__(self): |
+ inner_string = self.inner_string |
+ if self.is_nullable: |
+ # FIXME: Dictionary::ConversionContext::setConversionType can't |
+ # handle the '?' in nullable types (passes nullability separately). |
+ # Update that function to handle nullability from the type name, |
+ # simplifying its signature. |
+ # return inner_string + '?' |
+ return inner_string |
+ return inner_string |
+ |
+ @property |
+ def inner_string(self): |
+ raise NotImplementedError( |
+ 'inner_string property should be defined in subclasses') |
+ |
+ @property |
+ def is_basic_type(self): |
+ return False |
+ |
+ @property |
+ def is_callback_function(self): |
+ return False |
+ |
+ @property |
+ def is_callback_interface(self): |
+ return False |
+ |
+ @property |
+ def is_dictionary(self): |
+ return False |
+ |
+ @property |
+ def is_enum(self): |
+ return False |
+ |
+ @property |
+ def is_integer_type(self): |
+ return False |
+ |
+ @property |
+ def is_numeric_type(self): |
+ return False |
+ |
+ @property |
+ def is_primitive_type(self): |
+ return False |
+ |
+ @property |
+ def is_interface_type(self): |
+ return False |
+ |
+ @property |
+ def is_string_type(self): |
+ return False |
+ |
+ @property |
+ def is_union_type(self): |
+ return False |
+ |
+ @property |
+ def may_raise_exception_on_conversion(self): |
+ return False |
+ |
+ @property |
+ def name(self): |
+ if self.is_nullable: |
+ return self.inner_name + 'OrNull' |
+ return self.inner_name |
+ |
+ @property |
+ def inner_name(self): |
+ raise NotImplementedError( |
+ 'inner_name property should be defined in subclasses') |
+ |
+ def resolve_typedefs(self, typedefs): |
+ raise NotImplementedError( |
+ 'resolve_typedefs should be defined in subclasses') |
+ |
+ |
################################################################################ |
# IdlType |
################################################################################ |
-class IdlType(object): |
+class IdlType(IdlTypeBase): |
# FIXME: incorporate Nullable, etc. |
- # FIXME: use nested types: IdlArrayType, IdlNullableType, IdlSequenceType |
# to support types like short?[] vs. short[]?, instead of treating these |
# as orthogonal properties (via flags). |
callback_functions = set() |
callback_interfaces = set() |
+ dictionaries = set() |
enums = {} # name -> values |
- def __init__(self, base_type, is_array=False, is_sequence=False, is_nullable=False, is_unrestricted=False): |
- if is_array and is_sequence: |
- raise ValueError('Array of Sequences are not allowed.') |
+ def __init__(self, base_type, is_nullable=False, is_unrestricted=False): |
+ super(IdlType, self).__init__(is_nullable) |
if is_unrestricted: |
self.base_type = 'unrestricted %s' % base_type |
else: |
self.base_type = base_type |
- self.is_array = is_array |
- self.is_sequence = is_sequence |
- self.is_nullable = is_nullable |
- def __str__(self): |
- type_string = self.base_type |
- if self.is_array: |
- return type_string + '[]' |
- if self.is_sequence: |
- return 'sequence<%s>' % type_string |
- if self.is_nullable: |
- # FIXME: Dictionary::ConversionContext::setConversionType can't |
- # handle the '?' in nullable types (passes nullability separately). |
- # Update that function to handle nullability from the type name, |
- # simplifying its signature. |
- # return type_string + '?' |
- return type_string |
- return type_string |
- |
- # FIXME: rename to native_array_element_type and move to v8_types.py |
- @property |
- def array_or_sequence_type(self): |
- return self.array_type or self.sequence_type |
- |
- # FIXME: rename to array_element_type |
@property |
- def array_type(self): |
- return self.is_array and IdlType(self.base_type) |
- |
- # FIXME: rename to sequence_element_type |
- @property |
- def sequence_type(self): |
- return self.is_sequence and IdlType(self.base_type) |
+ def inner_string(self): |
+ return self.base_type |
@property |
def is_basic_type(self): |
- return self.base_type in BASIC_TYPES and not self.array_or_sequence_type |
+ return self.base_type in BASIC_TYPES |
@property |
def is_callback_function(self): |
@@ -153,11 +222,8 @@ class IdlType(object): |
return self.base_type in IdlType.callback_interfaces |
@property |
- def is_composite_type(self): |
- return (self.name == 'Any' or |
- self.array_type or |
- self.sequence_type or |
- self.is_union_type) |
+ def is_dictionary(self): |
+ return self.base_type in IdlType.dictionaries |
@property |
def is_enum(self): |
@@ -171,15 +237,15 @@ class IdlType(object): |
@property |
def is_integer_type(self): |
- return self.base_type in INTEGER_TYPES and not self.array_or_sequence_type |
+ return self.base_type in INTEGER_TYPES |
@property |
def is_numeric_type(self): |
- return self.base_type in NUMERIC_TYPES and not self.array_or_sequence_type |
+ return self.base_type in NUMERIC_TYPES |
@property |
def is_primitive_type(self): |
- return self.base_type in PRIMITIVE_TYPES and not self.array_or_sequence_type |
+ return self.base_type in PRIMITIVE_TYPES |
@property |
def is_interface_type(self): |
@@ -188,31 +254,34 @@ class IdlType(object): |
# http://www.w3.org/TR/WebIDL/#idl-interface |
# In C++ these are RefPtr or PassRefPtr types. |
return not(self.is_basic_type or |
- self.is_composite_type or |
self.is_callback_function or |
+ self.is_dictionary or |
self.is_enum or |
+ self.name == 'Any' or |
self.name == 'Object' or |
self.name == 'Promise') # Promise will be basic in future |
@property |
+ def is_string_type(self): |
+ return self.inner_name in STRING_TYPES |
+ |
+ @property |
+ def may_raise_exception_on_conversion(self): |
+ return (self.is_integer_type or |
+ self.name in ('ByteString', 'ScalarValueString')) |
+ |
+ @property |
def is_union_type(self): |
return isinstance(self, IdlUnionType) |
@property |
- def name(self): |
- """Return type name. |
+ def inner_name(self): |
+ """Return type name (or inner type name if nullable) |
http://heycam.github.io/webidl/#dfn-type-name |
""" |
base_type = self.base_type |
- base_type_name = TYPE_NAMES.get(base_type, base_type) |
- if self.is_array: |
- return base_type_name + 'Array' |
- if self.is_sequence: |
- return base_type_name + 'Sequence' |
- if self.is_nullable: |
- return base_type_name + 'OrNull' |
- return base_type_name |
+ return TYPE_NAMES.get(base_type, base_type) |
@classmethod |
def set_callback_functions(cls, new_callback_functions): |
@@ -223,10 +292,17 @@ class IdlType(object): |
cls.callback_interfaces.update(new_callback_interfaces) |
@classmethod |
+ def set_dictionaries(cls, new_dictionaries): |
+ cls.dictionaries.update(new_dictionaries) |
+ |
+ @classmethod |
def set_enums(cls, new_enums): |
cls.enums.update(new_enums) |
def resolve_typedefs(self, typedefs): |
+ # This function either returns |self|, possibly mutated, or leaves this |
+ # object unmodified and returns a different object. |
+ # FIXME: Change to never mutate |self|, and rename typedefs_resolved(). |
if self.base_type not in typedefs: |
return self |
new_type = typedefs[self.base_type] |
@@ -235,16 +311,7 @@ class IdlType(object): |
# since can't change type(self) |
return new_type |
# If type doesn't change, just mutate self to avoid a new object |
- # FIXME: a bit ugly; use __init__ instead of setting flags |
- self.base_type = new_type.base_type |
- # handle array both in use and in typedef itself: |
- # typedef Type TypeDef; |
- # TypeDef[] ... |
- # and: |
- # typedef Type[] TypeArray |
- # TypeArray ... |
- self.is_array |= new_type.is_array |
- self.is_sequence |= new_type.is_sequence |
+ self.__init__(new_type.base_type, self.is_nullable or new_type.is_nullable) |
return self |
@@ -252,70 +319,68 @@ class IdlType(object): |
# IdlUnionType |
################################################################################ |
-class IdlUnionType(object): |
+class IdlUnionType(IdlTypeBase): |
# http://heycam.github.io/webidl/#idl-union |
- # FIXME: derive from IdlType, instead of stand-alone class, to reduce |
- # duplication. |
def __init__(self, member_types, is_nullable=False): |
+ super(IdlUnionType, self).__init__(is_nullable=is_nullable) |
self.member_types = member_types |
- self.is_nullable = is_nullable |
@property |
- def array_or_sequence_type(self): |
- return False |
+ def is_union_type(self): |
+ return True |
@property |
- def array_type(self): |
- return False |
+ def inner_name(self): |
+ """Return type name (or inner type name if nullable) |
- @property |
- def is_array(self): |
- # We do not support arrays of union types |
- return False |
+ http://heycam.github.io/webidl/#dfn-type-name |
+ """ |
+ return 'Or'.join(member_type.name for member_type in self.member_types) |
- @property |
- def base_type(self): |
- return None |
+ def resolve_typedefs(self, typedefs): |
+ self.member_types = [ |
+ typedefs.get(member_type, member_type) |
+ for member_type in self.member_types] |
+ return self |
- @property |
- def is_basic_type(self): |
- return False |
- @property |
- def is_callback_function(self): |
- return False |
+################################################################################ |
+# IdlArrayOrSequenceType, IdlArrayType, IdlSequenceType |
+################################################################################ |
- @property |
- def is_enum(self): |
- return False |
+class IdlArrayOrSequenceType(IdlTypeBase): |
+ """Base class for IdlArrayType and IdlSequenceType.""" |
- @property |
- def is_integer_type(self): |
- return False |
+ def __init__(self, element_type, is_nullable=False): |
+ super(IdlArrayOrSequenceType, self).__init__(is_nullable) |
+ self.element_type = element_type |
- @property |
- def is_numeric_type(self): |
- return False |
+ def resolve_typedefs(self, typedefs): |
+ self.element_type = self.element_type.resolve_typedefs(typedefs) |
+ return self |
- @property |
- def is_primitivee_type(self): |
- return False |
+ |
+class IdlArrayType(IdlArrayOrSequenceType): |
+ def __init__(self, element_type, is_nullable=False): |
+ super(IdlArrayType, self).__init__(element_type, is_nullable) |
@property |
- def is_sequence(self): |
- # We do not support sequences of union types |
- return False |
+ def inner_string(self): |
+ return '%s[]' % self.element_type |
@property |
- def is_union_type(self): |
- return True |
+ def inner_name(self): |
+ return self.element_type.name + 'Array' |
+ |
+ |
+class IdlSequenceType(IdlArrayOrSequenceType): |
+ def __init__(self, element_type, is_nullable=False): |
+ super(IdlSequenceType, self).__init__(element_type, is_nullable) |
@property |
- def name(self): |
- return 'Or'.join(member_type.name for member_type in self.member_types) |
+ def inner_string(self): |
+ return 'sequence<%s>' % self.element_type |
- def resolve_typedefs(self, typedefs): |
- self.member_types = [ |
- typedefs.get(member_type, member_type) |
- for member_type in self.member_types] |
- return self |
+ @property |
+ def inner_name(self): |
+ return self.element_type.name + 'Sequence' |