Commit bd99b789 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

IDL compiler: Support iterable/maplike/setlike declarations

Bug: 839389
Change-Id: Ied3e43e81c38bc6f941e87dc4ca35e7bef1ad1e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2155745
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#760397}
parent 7b80f9c8
......@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import itertools
from .code_generator_info import CodeGeneratorInfo
from .composition_parts import WithCodeGeneratorInfo
from .composition_parts import WithComponent
......@@ -62,10 +64,14 @@ class CallbackInterface(UserDefinedType, WithExtendedAttributes,
self.operation_groups = []
def iter_all_members(self):
for constant in self.constants:
yield constant
for operation in self.operations:
yield operation
list_of_members = [
self.constants,
self.operations,
]
return itertools.chain(*list_of_members)
def iter_all_overload_groups(self):
return iter(self.operation_groups)
def __init__(self, ir):
assert isinstance(ir, CallbackInterface.IR)
......
......@@ -484,31 +484,38 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase()
for old_ir in old_irs:
assert not old_ir.constructor_groups
assert not old_ir.named_constructor_groups
assert not old_ir.operation_groups
new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
def make_groups(group_ir_class, operations):
sort_key = lambda x: x.identifier
new_ir.constructor_groups = [
ConstructorGroup.IR(constructors=list(constructors))
for identifier, constructors in itertools.groupby(
sorted(new_ir.constructors, key=sort_key), key=sort_key)
]
new_ir.named_constructor_groups = [
ConstructorGroup.IR(constructors=list(constructors))
for identifier, constructors in itertools.groupby(
sorted(new_ir.named_constructors, key=sort_key),
key=sort_key)
]
new_ir.operation_groups = [
OperationGroup.IR(operations=list(operations))
for identifier, operations in itertools.groupby(
sorted(new_ir.operations, key=sort_key), key=sort_key)
return [
group_ir_class(list(operations_in_group))
for identifier, operations_in_group in itertools.groupby(
sorted(operations, key=sort_key), key=sort_key)
if identifier
]
for old_ir in old_irs:
new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
assert not new_ir.constructor_groups
assert not new_ir.named_constructor_groups
assert not new_ir.operation_groups
new_ir.constructor_groups = make_groups(ConstructorGroup.IR,
new_ir.constructors)
new_ir.named_constructor_groups = make_groups(
ConstructorGroup.IR, new_ir.named_constructors)
new_ir.operation_groups = make_groups(OperationGroup.IR,
new_ir.operations)
if not isinstance(new_ir, Interface.IR):
continue
for item in (new_ir.iterable, new_ir.maplike, new_ir.setlike):
if item:
assert not item.operation_groups
item.operation_groups = make_groups(
OperationGroup.IR, item.operations)
def _propagate_extattrs_to_overload_group(self):
ANY_OF = ('CrossOrigin', 'Custom', 'LenientThis', 'NotEnumerable',
'PerWorldBindings', 'SecureContext', 'Unforgeable',
......@@ -523,9 +530,7 @@ class IdlCompiler(object):
new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
for group in itertools.chain(new_ir.constructor_groups,
new_ir.named_constructor_groups,
new_ir.operation_groups):
for group in new_ir.iter_all_overload_groups():
for key in ANY_OF:
if any(key in overload.extended_attributes
for overload in group):
......@@ -547,9 +552,7 @@ class IdlCompiler(object):
new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir)
for group in itertools.chain(new_ir.constructor_groups,
new_ir.named_constructor_groups,
new_ir.operation_groups):
for group in new_ir.iter_all_overload_groups():
exposures = map(lambda overload: overload.exposure, group)
# [Exposed]
......
......@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import itertools
from .attribute import Attribute
from .code_generator_info import CodeGeneratorInfo
from .composition_parts import WithCodeGeneratorInfo
......@@ -71,12 +73,15 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
self.operation_groups = []
def iter_all_members(self):
for attribute in self.attributes:
yield attribute
for constant in self.constants:
yield constant
for operation in self.operations:
yield operation
list_of_members = [
self.attributes,
self.constants,
self.operations,
]
return itertools.chain(*list_of_members)
def iter_all_overload_groups(self):
return iter(self.operation_groups)
def __init__(self, ir):
assert isinstance(ir, Namespace.IR)
......
......@@ -61,6 +61,8 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
self.is_deleter = is_deleter
self.is_stringifier = False
self.stringifier_attribute = None
self.is_iterator = False
self.is_optionally_defined = False
def __init__(self, ir, owner):
assert isinstance(ir, Operation.IR)
......@@ -79,6 +81,8 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
self._is_deleter = ir.is_deleter
self._is_stringifier = ir.is_stringifier
self._stringifier_attribute = ir.stringifier_attribute
self._is_iterator = ir.is_iterator
self._is_optionally_defined = ir.is_optionally_defined
@property
def is_special_operation(self):
......@@ -95,24 +99,49 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
@property
def is_getter(self):
"""Returns True if this is an indexed or named getter operation."""
return self._is_getter
@property
def is_setter(self):
"""Returns True if this is an indexed or named setter operation."""
return self._is_setter
@property
def is_deleter(self):
"""Returns True if this is a named deleter operation."""
return self._is_deleter
@property
def is_stringifier(self):
"""Returns True if this is a stringifier operation."""
return self._is_stringifier
@property
def stringifier_attribute(self):
"""
Returns the identifier of an attribute when the stringifying target is
an attribute.
"""
return self._stringifier_attribute
@property
def is_iterator(self):
"""
Returns True if this operation must be exposed as @@iterator in
addition to a property with the identifier.
"""
return self._is_iterator
@property
def is_optionally_defined(self):
"""
Returns True if this operation will be defined only when the interface
doesn't declare a member with the same identifier, i.e. this operation
will be shadowed by an own member declaration.
"""
return self._is_optionally_defined
class OperationGroup(OverloadGroup, WithExtendedAttributes,
WithCodeGeneratorInfo, WithExposure, WithOwner,
......
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