Commit 8297af31 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

IDL compiler: Remove AnnotatedType

Bug: 839389
Change-Id: Ib131f7dcc043af790bd91ec586f52c4849591165
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1695748Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676361}
parent 0881b120
...@@ -162,6 +162,9 @@ class ExtendedAttributes(object): ...@@ -162,6 +162,9 @@ class ExtendedAttributes(object):
for k, v in groupby(attributes, key=lambda x: x.key) for k, v in groupby(attributes, key=lambda x: x.key)
} }
def __bool__(self):
return bool(self._attributes)
def __contains__(self, key): def __contains__(self, key):
""" """
Returns True if this has an extended attribute with the |key|. Returns True if this has an extended attribute with the |key|.
...@@ -178,6 +181,9 @@ class ExtendedAttributes(object): ...@@ -178,6 +181,9 @@ class ExtendedAttributes(object):
for attr in attrs: for attr in attrs:
yield attr yield attr
def __len__(self):
return len(list(self.__iter__()))
def __str__(self): def __str__(self):
attrs = [str(attr) for attr in self] attrs = [str(attr) for attr in self]
return '[{}]'.format(', '.join(attrs)) return '[{}]'.format(', '.join(attrs))
...@@ -185,6 +191,9 @@ class ExtendedAttributes(object): ...@@ -185,6 +191,9 @@ class ExtendedAttributes(object):
def make_copy(self): def make_copy(self):
return ExtendedAttributes(map(ExtendedAttribute.make_copy, self)) return ExtendedAttributes(map(ExtendedAttribute.make_copy, self))
def keys(self):
return self._attributes.keys()
def get(self, key): def get(self, key):
""" """
Returns an exnteded attribute whose key is |key|. Returns an exnteded attribute whose key is |key|.
......
...@@ -27,10 +27,9 @@ from .user_defined_type import UserDefinedType ...@@ -27,10 +27,9 @@ from .user_defined_type import UserDefinedType
# + PromiseType # + PromiseType
# + UnionType # + UnionType
# + NullableType # + NullableType
# + AnnotatedType
class IdlType(WithCodeGeneratorInfo, WithDebugInfo): class IdlType(WithExtendedAttributes, WithCodeGeneratorInfo, WithDebugInfo):
""" """
Represents a 'type' in Web IDL Represents a 'type' in Web IDL
...@@ -43,36 +42,35 @@ class IdlType(WithCodeGeneratorInfo, WithDebugInfo): ...@@ -43,36 +42,35 @@ class IdlType(WithCodeGeneratorInfo, WithDebugInfo):
language bindings (such as ECMAScript bindings), thus it's out of scope for language bindings (such as ECMAScript bindings), thus it's out of scope for
IdlType to tell whether IDL dictionary type accepts ES null value or not. IdlType to tell whether IDL dictionary type accepts ES null value or not.
*CAUTION*: Predicators are defined based on the exact definition of Web Nullable type and typedef are implemented as if they're a container type
IDL, and may behave counterintuitively. See examples below. like record type and promise type.
clamp_nullable_long = ...an IdlType of '[Clamp] long?'
isisntance(clamp_nullable_long, AnnotatedType) # True
clamp_nullable_long.is_annotated # True
clamp_nullable_long.is_nullable # False, this is not a NullableType
nullable_long = clamp_nullable_long.inner_type
isinstance(nullable_long, NullableType) # True
nullable_long.is_nullable # True
nullable_long.is_numeric # False, NullableType is not a numeric type
long_type = nullable_long.inner_type
isinstance(long_type, SimpleType) # True
long_type.is_numeric # True
""" """
def __init__(self, code_generator_info=None, debug_info=None): def __init__(self,
extended_attributes=None,
code_generator_info=None,
debug_info=None):
WithExtendedAttributes.__init__(self, extended_attributes)
WithCodeGeneratorInfo.__init__(self, code_generator_info) WithCodeGeneratorInfo.__init__(self, code_generator_info)
WithDebugInfo.__init__(self, debug_info) WithDebugInfo.__init__(self, debug_info)
def __str__(self): def __str__(self):
return self.syntactic_form
@property
def syntactic_form(self):
"""
Returns a text representation of the type in the form of Web IDL syntax.
@return str
"""
raise exceptions.NotImplementedError() raise exceptions.NotImplementedError()
@property @property
def type_name(self): def type_name(self):
""" """
Returns type name of this type. Returns the type name.
https://heycam.github.io/webidl/#dfn-type-name https://heycam.github.io/webidl/#dfn-type-name
Note that a type name is not necessarily unique.
@return str @return str
""" """
raise exceptions.NotImplementedError() raise exceptions.NotImplementedError()
...@@ -213,10 +211,10 @@ class IdlType(WithCodeGeneratorInfo, WithDebugInfo): ...@@ -213,10 +211,10 @@ class IdlType(WithCodeGeneratorInfo, WithDebugInfo):
@property @property
def is_annotated(self): def is_annotated(self):
""" """
Returns True if |self| is an annotated type. Returns True if |self| is annotated.
@return bool @return bool
""" """
return False return bool(self.extended_attributes)
@property @property
def is_promise(self): def is_promise(self):
...@@ -258,6 +256,18 @@ class IdlType(WithCodeGeneratorInfo, WithDebugInfo): ...@@ -258,6 +256,18 @@ class IdlType(WithCodeGeneratorInfo, WithDebugInfo):
""" """
return False return False
def _format_syntactic_form(self, syntactic_form_inner):
"""Helper function to implement |syntactic_form|."""
if self.extended_attributes:
return '{} {}'.format(self.extended_attributes,
syntactic_form_inner)
return syntactic_form_inner
def _format_type_name(self, type_name_inner):
"""Helper function to implement |type_name|."""
return '{}{}'.format(type_name_inner, ''.join(
sorted(self.extended_attributes.keys())))
class SimpleType(IdlType): class SimpleType(IdlType):
""" """
...@@ -274,24 +284,30 @@ class SimpleType(IdlType): ...@@ -274,24 +284,30 @@ class SimpleType(IdlType):
_VALID_TYPES = ('any', 'boolean', 'object', 'symbol', _VALID_TYPES = ('any', 'boolean', 'object', 'symbol',
'void') + _NUMERIC_TYPES + _STRING_TYPES 'void') + _NUMERIC_TYPES + _STRING_TYPES
def __init__(self, name, code_generator_info=None, debug_info=None): def __init__(self,
name,
extended_attributes=None,
code_generator_info=None,
debug_info=None):
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
assert name in SimpleType._VALID_TYPES, ( assert name in SimpleType._VALID_TYPES, (
'Unknown type name: {}'.format(name)) 'Unknown type name: {}'.format(name))
self._name = name self._name = name
def __str__(self):
return self._name
# IdlType overrides # IdlType overrides
@property
def syntactic_form(self):
return self._format_syntactic_form(self._name)
@property @property
def type_name(self): def type_name(self):
if str(self) == 'DOMString': name = 'String' if self._name == 'DOMString' else self._name
return 'String' return self._format_type_name(
return NameStyleConverter(self._name).to_upper_camel_case() NameStyleConverter(name).to_upper_camel_case())
@property @property
def is_numeric(self): def is_numeric(self):
...@@ -340,11 +356,13 @@ class ReferenceType(IdlType, WithIdentifier, Proxy): ...@@ -340,11 +356,13 @@ class ReferenceType(IdlType, WithIdentifier, Proxy):
def __init__(self, def __init__(self,
ref_to_idl_type, ref_to_idl_type,
extended_attributes=None,
code_generator_info=None, code_generator_info=None,
debug_info=None): debug_info=None):
assert RefByIdFactory.is_reference(ref_to_idl_type) assert RefByIdFactory.is_reference(ref_to_idl_type)
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
WithIdentifier.__init__(self, ref_to_idl_type.identifier) WithIdentifier.__init__(self, ref_to_idl_type.identifier)
...@@ -376,6 +394,16 @@ class DefinitionType(IdlType, WithIdentifier): ...@@ -376,6 +394,16 @@ class DefinitionType(IdlType, WithIdentifier):
# TODO(peria): Consider exposing access of |_definition| # TODO(peria): Consider exposing access of |_definition|
# IdlType overrides # IdlType overrides
@property
def syntactic_form(self):
assert not self.extended_attributes
return self.identifier
@property
def type_name(self):
assert not self.extended_attributes
return self.identifier
@property @property
def is_interface(self): def is_interface(self):
return self._definition.is_interface return self._definition.is_interface
...@@ -404,7 +432,7 @@ class TypedefType(IdlType, WithIdentifier): ...@@ -404,7 +432,7 @@ class TypedefType(IdlType, WithIdentifier):
'typedef' in Web IDL is not a type, however, there are use cases that have 'typedef' in Web IDL is not a type, however, there are use cases that have
interest in typedef names. Thus, the IDL compiler does not resolve interest in typedef names. Thus, the IDL compiler does not resolve
typedefs transparently (i.e. does not remove typedefs entirely), and typedefs transparently (i.e. does not remove typedefs entirely), and
IdlTypes representing typedefs remain and behave like AnnotatedType. You IdlTypes representing typedefs remain and behave like NullableType. You
can track down the typedef'ed type to |original_type|. can track down the typedef'ed type to |original_type|.
""" """
...@@ -425,8 +453,14 @@ class TypedefType(IdlType, WithIdentifier): ...@@ -425,8 +453,14 @@ class TypedefType(IdlType, WithIdentifier):
return self._typedef.idl_type return self._typedef.idl_type
# IdlType overrides # IdlType overrides
@property
def syntactic_form(self):
assert not self.extended_attributes
return self.identifier
@property @property
def type_name(self): def type_name(self):
assert not self.extended_attributes
return self.original_type.type_name return self.original_type.type_name
@property @property
...@@ -439,10 +473,14 @@ class TypedefType(IdlType, WithIdentifier): ...@@ -439,10 +473,14 @@ class TypedefType(IdlType, WithIdentifier):
class _ArrayLikeType(IdlType): class _ArrayLikeType(IdlType):
def __init__(self, element_type, code_generator_info=None, def __init__(self,
element_type,
extended_attributes=None,
code_generator_info=None,
debug_info=None): debug_info=None):
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
assert isinstance(element_type, IdlType) assert isinstance(element_type, IdlType)
...@@ -454,17 +492,28 @@ class _ArrayLikeType(IdlType): ...@@ -454,17 +492,28 @@ class _ArrayLikeType(IdlType):
class SequenceType(_ArrayLikeType): class SequenceType(_ArrayLikeType):
def __init__(self, element_type, code_generator_info=None, def __init__(self,
element_type,
extended_attributes=None,
code_generator_info=None,
debug_info=None): debug_info=None):
_ArrayLikeType.__init__(self, element_type) _ArrayLikeType.__init__(
self,
element_type,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info,
debug_info=debug_info)
# IdlType overrides # IdlType overrides
def __str__(self): @property
return 'sequence<{}>'.format(self.element_type) def syntactic_form(self):
return self._format_syntactic_form('sequence<{}>'.format(
self.element_type.syntactic_form))
@property @property
def type_name(self): def type_name(self):
return self.element_type.type_name + 'Sequence' return self._format_type_name('{}Sequence'.format(
self.element_type.type_name))
@property @property
def is_sequence(self): def is_sequence(self):
...@@ -472,17 +521,28 @@ class SequenceType(_ArrayLikeType): ...@@ -472,17 +521,28 @@ class SequenceType(_ArrayLikeType):
class FrozenArrayType(_ArrayLikeType): class FrozenArrayType(_ArrayLikeType):
def __init__(self, element_type, code_generator_info=None, def __init__(self,
element_type,
extended_attributes=None,
code_generator_info=None,
debug_info=None): debug_info=None):
_ArrayLikeType.__init__(self, element_type) _ArrayLikeType.__init__(
self,
element_type,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info,
debug_info=debug_info)
# IdlType overrides # IdlType overrides
def __str__(self): @property
return 'FrozenArray<{}>'.format(self.element_type) def syntactic_form(self):
return self._format_syntactic_form('FrozenArray<{}>'.format(
self.element_type.syntactic_form))
@property @property
def type_name(self): def type_name(self):
return self.element_type.type_name + 'Array' return self._format_type_name('{}Array'.format(
self.element_type.type_name))
@property @property
def is_frozen_array(self): def is_frozen_array(self):
...@@ -493,10 +553,12 @@ class RecordType(IdlType): ...@@ -493,10 +553,12 @@ class RecordType(IdlType):
def __init__(self, def __init__(self,
key_type, key_type,
value_type, value_type,
extended_attributes=None,
code_generator_info=None, code_generator_info=None,
debug_info=None): debug_info=None):
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
assert isinstance(key_type, IdlType) assert isinstance(key_type, IdlType)
...@@ -522,12 +584,15 @@ class RecordType(IdlType): ...@@ -522,12 +584,15 @@ class RecordType(IdlType):
return self._value_type return self._value_type
# IdlType overrides # IdlType overrides
def __str__(self): @property
return 'record<{}, {}>'.format(self.key_type, self.value_type) def syntactic_form(self):
return self._format_syntactic_form('record<{}, {}>'.format(
self.key_type.syntactic_form, self.value_type.syntactic_form))
@property @property
def type_name(self): def type_name(self):
return self.key_type.type_name + self.value_type.type_name + 'Record' return self._format_type_name('{}{}Record'.format(
self.key_type.type_name, self.value_type.type_name))
@property @property
def is_record(self): def is_record(self):
...@@ -535,9 +600,14 @@ class RecordType(IdlType): ...@@ -535,9 +600,14 @@ class RecordType(IdlType):
class PromiseType(IdlType): class PromiseType(IdlType):
def __init__(self, result_type, code_generator_info=None, debug_info=None): def __init__(self,
result_type,
extended_attributes=None,
code_generator_info=None,
debug_info=None):
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
assert isinstance(result_type, IdlType) assert isinstance(result_type, IdlType)
...@@ -552,12 +622,15 @@ class PromiseType(IdlType): ...@@ -552,12 +622,15 @@ class PromiseType(IdlType):
return self._result_type return self._result_type
# IdlType overrides # IdlType overrides
def __str__(self): @property
return 'Promise<{}>'.format(self.result_type) def syntactic_form(self):
return self._format_syntactic_form('Promise<{}>'.format(
self.result_type.syntactic_form))
@property @property
def type_name(self): def type_name(self):
return self.result_type.type_name + 'Promise' return self._format_type_name('{}Promise'.format(
self.result_type.type_name))
@property @property
def is_promise(self): def is_promise(self):
...@@ -566,10 +639,14 @@ class PromiseType(IdlType): ...@@ -566,10 +639,14 @@ class PromiseType(IdlType):
# https://heycam.github.io/webidl/#idl-union # https://heycam.github.io/webidl/#idl-union
class UnionType(IdlType): class UnionType(IdlType):
def __init__(self, member_types, code_generator_info=None, def __init__(self,
member_types,
extended_attributes=None,
code_generator_info=None,
debug_info=None): debug_info=None):
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
assert isinstance(member_types, (list, tuple)) assert isinstance(member_types, (list, tuple))
...@@ -591,8 +668,8 @@ class UnionType(IdlType): ...@@ -591,8 +668,8 @@ class UnionType(IdlType):
def flattened_member_types(self): def flattened_member_types(self):
""" """
Returns a set of flattened member types. Returns a set of flattened member types.
NOTE: Returned set does not contain nullable types nor annotated types, NOTE: Returned set does not contain nullable types even if |self|
even if |self| contains nullable/annotated types in its members. contains nullable types in its members.
https://heycam.github.io/webidl/#dfn-flattened-union-member-types https://heycam.github.io/webidl/#dfn-flattened-union-member-types
@return set(IdlType) @return set(IdlType)
""" """
...@@ -600,12 +677,15 @@ class UnionType(IdlType): ...@@ -600,12 +677,15 @@ class UnionType(IdlType):
assert False, 'Not implemented yet' assert False, 'Not implemented yet'
# IdlType overrides # IdlType overrides
def __str__(self): @property
return '({})'.format(' or '.join([str(t) for t in self.member_types])) def syntactic_form(self):
return self._format_syntactic_form('({})'.format(' or '.join(
[member.syntactic_form for member in self.member_types])))
@property @property
def type_name(self): def type_name(self):
return 'Or'.join([member.type_name for member in self.member_types]) return self._format_type_name('Or'.join(
[member.type_name for member in self.member_types]))
@property @property
def does_include_nullable_type(self): def does_include_nullable_type(self):
...@@ -618,64 +698,45 @@ class UnionType(IdlType): ...@@ -618,64 +698,45 @@ class UnionType(IdlType):
class NullableType(IdlType): class NullableType(IdlType):
def __init__(self, inner_type, code_generator_info=None, debug_info=None):
IdlType.__init__(
self,
code_generator_info=code_generator_info,
debug_info=debug_info)
assert isinstance(inner_type, IdlType)
self._inner_type = inner_type
# IdlType overrides
def __str__(self):
return '{}?'.format(self.inner_type)
@property
def type_name(self):
return self.inner_type.type_name + 'OrNull'
@property
def does_include_nullable_type(self):
return True
@property
def is_nullable(self):
return True
@property
def inner_type(self):
return self._inner_type
class AnnotatedType(IdlType, WithExtendedAttributes):
def __init__(self, def __init__(self,
inner_type, inner_type,
extended_attributes, extended_attributes=None,
code_generator_info=None, code_generator_info=None,
debug_info=None): debug_info=None):
IdlType.__init__( IdlType.__init__(
self, self,
extended_attributes=extended_attributes,
code_generator_info=code_generator_info, code_generator_info=code_generator_info,
debug_info=debug_info) debug_info=debug_info)
WithExtendedAttributes.__init__(self, extended_attributes)
assert isinstance(inner_type, IdlType) assert isinstance(inner_type, IdlType)
self._inner_type = inner_type self._inner_type = inner_type
# IdlType overrides # IdlType overrides
def __str__(self): @property
return '{} {}'.format(self.extended_attributes, self.inner_type) def syntactic_form(self):
assert not self.extended_attributes
return '{}?'.format(self.inner_type.syntactic_form)
@property @property
def type_name(self): def type_name(self):
return self.inner_type.type_name + ''.join( assert not self.extended_attributes
sorted([ext_attr.key for ext_attr in self.extended_attributes])) # https://heycam.github.io/webidl/#idl-annotated-types
# Web IDL seems not supposing a case of [X] ([Y] Type)?, i.e. something
# like [X] nullable<[Y] Type>, which should turn into "TypeYOrNullX".
#
# In case of '[Clamp] long?', it's interpreted as '([Clamp] long)?' but
# the type name must be "LongOrNullClamp" instead of "LongClampOrNull".
name = self.inner_type.type_name
ext_attrs = ''.join(sorted(self.inner_type.extended_attributes.keys()))
sep_index = len(name) - len(ext_attrs)
return '{}OrNull{}'.format(name[0:sep_index], name[sep_index:])
@property @property
def does_include_nullable_type(self): def does_include_nullable_type(self):
return self.inner_type.does_include_nullable_type return True
@property @property
def is_annotated(self): def is_nullable(self):
return True return True
@property @property
......
...@@ -6,7 +6,6 @@ import unittest ...@@ -6,7 +6,6 @@ import unittest
from .extended_attribute import ExtendedAttribute from .extended_attribute import ExtendedAttribute
from .extended_attribute import ExtendedAttributes from .extended_attribute import ExtendedAttributes
from .idl_types import AnnotatedType
from .idl_types import FrozenArrayType from .idl_types import FrozenArrayType
from .idl_types import NullableType from .idl_types import NullableType
from .idl_types import PromiseType from .idl_types import PromiseType
...@@ -44,10 +43,10 @@ class IdlTypesTest(unittest.TestCase): ...@@ -44,10 +43,10 @@ class IdlTypesTest(unittest.TestCase):
self.assertTrue(FrozenArrayType(short_type).is_frozen_array) self.assertTrue(FrozenArrayType(short_type).is_frozen_array)
self.assertTrue(UnionType([short_type, string_type]).is_union) self.assertTrue(UnionType([short_type, string_type]).is_union)
self.assertTrue(NullableType(short_type).is_nullable) self.assertTrue(NullableType(short_type).is_nullable)
annotated_type = AnnotatedType(short_type, ext_attrs) self.assertFalse(NullableType(short_type).is_numeric)
annotated_type = SimpleType('short', extended_attributes=ext_attrs)
self.assertTrue(annotated_type.is_annotated) self.assertTrue(annotated_type.is_annotated)
# Predictors are not transparent self.assertTrue(annotated_type.is_numeric)
self.assertFalse(annotated_type.is_numeric)
self.assertFalse(SimpleType('long').is_string) self.assertFalse(SimpleType('long').is_string)
self.assertFalse(SimpleType('DOMString').is_object) self.assertFalse(SimpleType('DOMString').is_object)
...@@ -85,15 +84,17 @@ class IdlTypesTest(unittest.TestCase): ...@@ -85,15 +84,17 @@ class IdlTypesTest(unittest.TestCase):
ext_attrs = ExtendedAttributes( ext_attrs = ExtendedAttributes(
[ExtendedAttribute('TreatNullAs', 'EmptyString')]) [ExtendedAttribute('TreatNullAs', 'EmptyString')])
self.assertEqual('StringTreatNullAs', self.assertEqual(
AnnotatedType(string_type, ext_attrs).type_name) 'StringTreatNullAs',
SimpleType('DOMString', extended_attributes=ext_attrs).type_name)
def test_union_types(self): def test_union_types(self):
# Test target: ((unrestricted double or object)? or # Test target: ((unrestricted double or object)? or
# [TreatNullAs=EmptyString] DOMString) # [TreatNullAs=EmptyString] DOMString)
treat_null_as = ExtendedAttribute('TreatNullAs', 'EmptyString') treat_null_as = ExtendedAttribute('TreatNullAs', 'EmptyString')
annotated_string = AnnotatedType( annotated_string = SimpleType(
SimpleType('DOMString'), ExtendedAttributes([treat_null_as])) 'DOMString',
extended_attributes=ExtendedAttributes([treat_null_as]))
obj = SimpleType('object') obj = SimpleType('object')
unrestricted_double = SimpleType('unrestricted double') unrestricted_double = SimpleType('unrestricted double')
union = UnionType( union = UnionType(
......
...@@ -10,7 +10,6 @@ from .dictionary import Dictionary ...@@ -10,7 +10,6 @@ from .dictionary import Dictionary
from .dictionary import DictionaryMember from .dictionary import DictionaryMember
from .enumeration import Enumeration from .enumeration import Enumeration
from .extended_attribute import ExtendedAttributes from .extended_attribute import ExtendedAttributes
from .idl_types import AnnotatedType
from .idl_types import FrozenArrayType from .idl_types import FrozenArrayType
from .idl_types import NullableType from .idl_types import NullableType
from .idl_types import PromiseType from .idl_types import PromiseType
...@@ -207,83 +206,76 @@ class _IRBuilder(object): ...@@ -207,83 +206,76 @@ class _IRBuilder(object):
return self._create_ref_to_idl_def(node.GetName()) return self._create_ref_to_idl_def(node.GetName())
def _build_type(self, node): def _build_type(self, node):
def build_maybe_inner_type(node):
return self._build_type_internal(node.GetChildren()[0])
def build_maybe_nullable_type(node):
maybe_inner_type = build_maybe_inner_type(node)
if node.GetProperty('NULLABLE'):
return NullableType(maybe_inner_type)
return maybe_inner_type
def build_maybe_annotated_type(node):
type_nodes = list(node.GetChildren())
extended_attributes = self._take_extended_attributes(type_nodes)
assert len(type_nodes) == 1
maybe_inner_type = build_maybe_nullable_type(node)
if extended_attributes:
return AnnotatedType(
inner_type=maybe_inner_type,
extended_attributes=extended_attributes)
return maybe_inner_type
assert node.GetClass() == 'Type' assert node.GetClass() == 'Type'
return build_maybe_annotated_type(node) if node.GetProperty('NULLABLE'):
return NullableType(self._build_type_internal(node.GetChildren()))
return self._build_type_internal(node.GetChildren())
def _build_type_internal(self, node): def _build_type_internal(self, nodes):
""" """
Args: Args:
node: The body node of the type definition, which is supposed to be nodes: The child nodes of a 'Type' node.
the first child of a 'Type' node.
""" """
def build_frozen_array_type(node): def build_frozen_array_type(node, extended_attributes):
assert len(node.GetChildren()) == 1 assert len(node.GetChildren()) == 1
return FrozenArrayType( return FrozenArrayType(
element_type=self._build_type(node.GetChildren()[0]), element_type=self._build_type(node.GetChildren()[0]),
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
def build_promise_type(node): def build_promise_type(node, extended_attributes):
assert len(node.GetChildren()) == 1 assert len(node.GetChildren()) == 1
return PromiseType( return PromiseType(
result_type=self._build_type(node.GetChildren()[0]), result_type=self._build_type(node.GetChildren()[0]),
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
def build_union_type(node): def build_union_type(node, extended_attributes):
union_type = UnionType( return UnionType(
member_types=map(self._build_type, node.GetChildren())) member_types=map(self._build_type, node.GetChildren()),
return union_type extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node))
def build_record_type(node): def build_record_type(node, extended_attributes):
key_node, value_node = node.GetChildren() key_node, value_node = node.GetChildren()
return RecordType( return RecordType(
# idl_parser doesn't produce a 'Type' node for the key type, # idl_parser doesn't produce a 'Type' node for the key type,
# hence we need to skip one level. # hence we need to skip one level.
key_type=self._build_type_internal(key_node), key_type=self._build_type_internal([key_node]),
value_type=self._build_type(value_node), value_type=self._build_type(value_node),
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
def build_reference_type(node): def build_reference_type(node, extended_attributes):
identifier = node.GetName() identifier = node.GetName()
ref_type = ReferenceType( return ReferenceType(
ref_to_idl_type=self._create_ref_to_idl_type(identifier), ref_to_idl_type=self._create_ref_to_idl_type(identifier),
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
return ref_type
def build_sequence_type(node): def build_sequence_type(node, extended_attributes):
return SequenceType( return SequenceType(
element_type=self._build_type(node.GetChildren()[0]), element_type=self._build_type(node.GetChildren()[0]),
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
def build_simple_type(node): def build_simple_type(node, extended_attributes):
type_name = node.GetName() name = node.GetName()
if type_name is None: if name is None:
assert node.GetClass() == 'Any' assert node.GetClass() == 'Any'
type_name = node.GetClass().lower() name = node.GetClass().lower()
if node.GetProperty('UNRESTRICTED'): if node.GetProperty('UNRESTRICTED'):
type_name = 'unrestricted ' + type_name name = 'unrestricted {}'.format(name)
return SimpleType( return SimpleType(
name=type_name, debug_info=self._build_debug_info(node)) name=name,
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node))
type_nodes = list(nodes)
extended_attributes = self._take_extended_attributes(type_nodes)
assert len(type_nodes) == 1
body_node = type_nodes[0]
build_functions = { build_functions = {
'Any': build_simple_type, 'Any': build_simple_type,
...@@ -296,7 +288,8 @@ class _IRBuilder(object): ...@@ -296,7 +288,8 @@ class _IRBuilder(object):
'Typeref': build_reference_type, 'Typeref': build_reference_type,
'UnionType': build_union_type, 'UnionType': build_union_type,
} }
return build_functions[node.GetClass()](node) return build_functions[body_node.GetClass()](body_node,
extended_attributes)
def _take_and_build(self, node_class, build_func, node_list): def _take_and_build(self, node_class, build_func, node_list):
""" """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment