diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py')
-rw-r--r-- | chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py b/chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py new file mode 100644 index 00000000000..e488e332648 --- /dev/null +++ b/chromium/third_party/WebKit/Source/bindings/scripts/idl_types.py @@ -0,0 +1,321 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""IDL type handling. + +Classes: +IdlType +IdlUnionType +""" + +from collections import defaultdict + + +################################################################################ +# IDL types +################################################################################ + +INTEGER_TYPES = frozenset([ + # http://www.w3.org/TR/WebIDL/#dfn-integer-type + 'byte', + 'octet', + 'short', + 'unsigned short', + # int and unsigned are not IDL types + 'long', + 'unsigned long', + 'long long', + 'unsigned long long', +]) +NUMERIC_TYPES = (INTEGER_TYPES | frozenset([ + # http://www.w3.org/TR/WebIDL/#dfn-numeric-type + 'float', + 'unrestricted float', + 'double', + 'unrestricted double', +])) +# http://www.w3.org/TR/WebIDL/#dfn-primitive-type +PRIMITIVE_TYPES = (frozenset(['boolean']) | NUMERIC_TYPES) +BASIC_TYPES = (PRIMITIVE_TYPES | frozenset([ + # Built-in, non-composite, non-object data types + # http://heycam.github.io/webidl/#idl-types + 'DOMString', + 'ByteString', + 'Date', + # http://heycam.github.io/webidl/#es-type-mapping + 'void', + # http://encoding.spec.whatwg.org/#type-scalarvaluestring + 'ScalarValueString', +])) +TYPE_NAMES = { + # http://heycam.github.io/webidl/#dfn-type-name + 'any': 'Any', + 'boolean': 'Boolean', + 'byte': 'Byte', + 'octet': 'Octet', + 'short': 'Short', + 'unsigned short': 'UnsignedShort', + 'long': 'Long', + 'unsigned long': 'UnsignedLong', + 'long long': 'LongLong', + 'unsigned long long': 'UnsignedLongLong', + 'float': 'Float', + 'unrestricted float': 'UnrestrictedFloat', + 'double': 'Double', + 'unrestricted double': 'UnrestrictedDouble', + 'DOMString': 'String', + 'ByteString': 'ByteString', + 'ScalarValueString': 'ScalarValueString', + 'object': 'Object', + 'Date': 'Date', +} + + +################################################################################ +# Inheritance +################################################################################ + +ancestors = defaultdict(list) # interface_name -> ancestors + +def inherits_interface(interface_name, ancestor_name): + return (interface_name == ancestor_name or + ancestor_name in ancestors[interface_name]) + + +def set_ancestors(new_ancestors): + ancestors.update(new_ancestors) + + +################################################################################ +# IdlType +################################################################################ + +class IdlType(object): + # 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() + 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.') + 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) + + @property + def is_basic_type(self): + return self.base_type in BASIC_TYPES and not self.array_or_sequence_type + + @property + def is_callback_function(self): + return self.base_type in IdlType.callback_functions + + @property + def is_callback_interface(self): + 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) + + @property + def is_enum(self): + # FIXME: add an IdlEnumType class and a resolve_enums step at end of + # IdlDefinitions constructor + return self.name in IdlType.enums + + @property + def enum_values(self): + return IdlType.enums[self.name] + + @property + def is_integer_type(self): + return self.base_type in INTEGER_TYPES and not self.array_or_sequence_type + + @property + def is_numeric_type(self): + return self.base_type in NUMERIC_TYPES and not self.array_or_sequence_type + + @property + def is_primitive_type(self): + return self.base_type in PRIMITIVE_TYPES and not self.array_or_sequence_type + + @property + def is_interface_type(self): + # Anything that is not another type is an interface type. + # http://www.w3.org/TR/WebIDL/#idl-types + # 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_enum or + self.name == 'Object' or + self.name == 'Promise') # Promise will be basic in future + + @property + def is_union_type(self): + return isinstance(self, IdlUnionType) + + @property + def name(self): + """Return type name. + + 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 + + @classmethod + def set_callback_functions(cls, new_callback_functions): + cls.callback_functions.update(new_callback_functions) + + @classmethod + def set_callback_interfaces(cls, new_callback_interfaces): + cls.callback_interfaces.update(new_callback_interfaces) + + @classmethod + def set_enums(cls, new_enums): + cls.enums.update(new_enums) + + def resolve_typedefs(self, typedefs): + if self.base_type not in typedefs: + return self + new_type = typedefs[self.base_type] + if type(new_type) != type(self): + # If type changes, need to return a different 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 + return self + + +################################################################################ +# IdlUnionType +################################################################################ + +class IdlUnionType(object): + # 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): + self.member_types = member_types + self.is_nullable = is_nullable + + @property + def array_or_sequence_type(self): + return False + + @property + def array_type(self): + return False + + @property + def is_array(self): + # We do not support arrays of union types + return False + + @property + def base_type(self): + return None + + @property + def is_basic_type(self): + return False + + @property + def is_callback_function(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_primitivee_type(self): + return False + + @property + def is_sequence(self): + # We do not support sequences of union types + return False + + @property + def is_union_type(self): + return True + + @property + def name(self): + return 'Or'.join(member_type.name for member_type in self.member_types) + + def resolve_typedefs(self, typedefs): + self.member_types = [ + typedefs.get(member_type, member_type) + for member_type in self.member_types] + return self |