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 @@ ...@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import itertools
from .code_generator_info import CodeGeneratorInfo from .code_generator_info import CodeGeneratorInfo
from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithCodeGeneratorInfo
from .composition_parts import WithComponent from .composition_parts import WithComponent
...@@ -62,10 +64,14 @@ class CallbackInterface(UserDefinedType, WithExtendedAttributes, ...@@ -62,10 +64,14 @@ class CallbackInterface(UserDefinedType, WithExtendedAttributes,
self.operation_groups = [] self.operation_groups = []
def iter_all_members(self): def iter_all_members(self):
for constant in self.constants: list_of_members = [
yield constant self.constants,
for operation in self.operations: self.operations,
yield operation ]
return itertools.chain(*list_of_members)
def iter_all_overload_groups(self):
return iter(self.operation_groups)
def __init__(self, ir): def __init__(self, ir):
assert isinstance(ir, CallbackInterface.IR) assert isinstance(ir, CallbackInterface.IR)
......
...@@ -484,31 +484,38 @@ class IdlCompiler(object): ...@@ -484,31 +484,38 @@ class IdlCompiler(object):
self._ir_map.move_to_new_phase() self._ir_map.move_to_new_phase()
for old_ir in old_irs: def make_groups(group_ir_class, operations):
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)
sort_key = lambda x: x.identifier sort_key = lambda x: x.identifier
new_ir.constructor_groups = [ return [
ConstructorGroup.IR(constructors=list(constructors)) group_ir_class(list(operations_in_group))
for identifier, constructors in itertools.groupby( for identifier, operations_in_group in itertools.groupby(
sorted(new_ir.constructors, key=sort_key), key=sort_key) sorted(operations, 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)
if identifier 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): def _propagate_extattrs_to_overload_group(self):
ANY_OF = ('CrossOrigin', 'Custom', 'LenientThis', 'NotEnumerable', ANY_OF = ('CrossOrigin', 'Custom', 'LenientThis', 'NotEnumerable',
'PerWorldBindings', 'SecureContext', 'Unforgeable', 'PerWorldBindings', 'SecureContext', 'Unforgeable',
...@@ -523,9 +530,7 @@ class IdlCompiler(object): ...@@ -523,9 +530,7 @@ class IdlCompiler(object):
new_ir = self._maybe_make_copy(old_ir) new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir) self._ir_map.add(new_ir)
for group in itertools.chain(new_ir.constructor_groups, for group in new_ir.iter_all_overload_groups():
new_ir.named_constructor_groups,
new_ir.operation_groups):
for key in ANY_OF: for key in ANY_OF:
if any(key in overload.extended_attributes if any(key in overload.extended_attributes
for overload in group): for overload in group):
...@@ -547,9 +552,7 @@ class IdlCompiler(object): ...@@ -547,9 +552,7 @@ class IdlCompiler(object):
new_ir = self._maybe_make_copy(old_ir) new_ir = self._maybe_make_copy(old_ir)
self._ir_map.add(new_ir) self._ir_map.add(new_ir)
for group in itertools.chain(new_ir.constructor_groups, for group in new_ir.iter_all_overload_groups():
new_ir.named_constructor_groups,
new_ir.operation_groups):
exposures = map(lambda overload: overload.exposure, group) exposures = map(lambda overload: overload.exposure, group)
# [Exposed] # [Exposed]
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import itertools
from .attribute import Attribute from .attribute import Attribute
from .code_generator_info import CodeGeneratorInfo from .code_generator_info import CodeGeneratorInfo
from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithCodeGeneratorInfo
...@@ -71,12 +73,15 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo, ...@@ -71,12 +73,15 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
self.operation_groups = [] self.operation_groups = []
def iter_all_members(self): def iter_all_members(self):
for attribute in self.attributes: list_of_members = [
yield attribute self.attributes,
for constant in self.constants: self.constants,
yield constant self.operations,
for operation in self.operations: ]
yield operation return itertools.chain(*list_of_members)
def iter_all_overload_groups(self):
return iter(self.operation_groups)
def __init__(self, ir): def __init__(self, ir):
assert isinstance(ir, Namespace.IR) assert isinstance(ir, Namespace.IR)
......
...@@ -61,6 +61,8 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo, ...@@ -61,6 +61,8 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
self.is_deleter = is_deleter self.is_deleter = is_deleter
self.is_stringifier = False self.is_stringifier = False
self.stringifier_attribute = None self.stringifier_attribute = None
self.is_iterator = False
self.is_optionally_defined = False
def __init__(self, ir, owner): def __init__(self, ir, owner):
assert isinstance(ir, Operation.IR) assert isinstance(ir, Operation.IR)
...@@ -79,6 +81,8 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo, ...@@ -79,6 +81,8 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
self._is_deleter = ir.is_deleter self._is_deleter = ir.is_deleter
self._is_stringifier = ir.is_stringifier self._is_stringifier = ir.is_stringifier
self._stringifier_attribute = ir.stringifier_attribute self._stringifier_attribute = ir.stringifier_attribute
self._is_iterator = ir.is_iterator
self._is_optionally_defined = ir.is_optionally_defined
@property @property
def is_special_operation(self): def is_special_operation(self):
...@@ -95,24 +99,49 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo, ...@@ -95,24 +99,49 @@ class Operation(FunctionLike, WithExtendedAttributes, WithCodeGeneratorInfo,
@property @property
def is_getter(self): def is_getter(self):
"""Returns True if this is an indexed or named getter operation."""
return self._is_getter return self._is_getter
@property @property
def is_setter(self): def is_setter(self):
"""Returns True if this is an indexed or named setter operation."""
return self._is_setter return self._is_setter
@property @property
def is_deleter(self): def is_deleter(self):
"""Returns True if this is a named deleter operation."""
return self._is_deleter return self._is_deleter
@property @property
def is_stringifier(self): def is_stringifier(self):
"""Returns True if this is a stringifier operation."""
return self._is_stringifier return self._is_stringifier
@property @property
def stringifier_attribute(self): def stringifier_attribute(self):
"""
Returns the identifier of an attribute when the stringifying target is
an attribute.
"""
return self._stringifier_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, class OperationGroup(OverloadGroup, WithExtendedAttributes,
WithCodeGeneratorInfo, WithExposure, WithOwner, 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