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

IDL compiler: Fix proxy from ReferenceType to DefinitionType/TypedefType

It's not yet been fully understood, but it seems like doubly-proxying
(ReferenceType = Proxy -> RefById -> DefinitionType/TypedefType) is
causing trouble.

This patch fixes the trouble, and makes a ReferenceType an instance
of IdlType (actually of ReferenceType).

Bug: 839389
Change-Id: Iccaa3ef78a1a77318e796248a1bf92a2eac40c80
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1892986Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712499}
parent 8b096f7a
......@@ -25,7 +25,6 @@ def build_database(filepaths, report_error):
assert callable(report_error)
ir_map = IRMap()
ref_to_idl_type_factory = RefByIdFactory()
ref_to_idl_def_factory = RefByIdFactory()
idl_type_factory = IdlTypeFactory()
......@@ -33,13 +32,11 @@ def build_database(filepaths, report_error):
filepaths=filepaths,
register_ir=ir_map.register,
create_ref_to_idl_def=ref_to_idl_def_factory.create,
create_ref_to_idl_type=ref_to_idl_type_factory.create,
idl_type_factory=idl_type_factory)
compiler = IdlCompiler(
ir_map=ir_map,
ref_to_idl_def_factory=ref_to_idl_def_factory,
ref_to_idl_type_factory=ref_to_idl_type_factory,
idl_type_factory=idl_type_factory,
report_error=report_error)
return compiler.build_database()
......@@ -46,15 +46,13 @@ class IdlCompiler(object):
Note that an old IR for 'x' remains internally. See IRMap for the details.
"""
def __init__(self, ir_map, ref_to_idl_def_factory, ref_to_idl_type_factory,
idl_type_factory, report_error):
def __init__(self, ir_map, ref_to_idl_def_factory, idl_type_factory,
report_error):
"""
Args:
ir_map: IRMap filled with the initial IRs of IDL definitions.
ref_to_idl_def_factory: RefByIdFactory that created all references
to UserDefinedType.
ref_to_idl_type_factory: RefByIdFactory that created all references
to IdlType.
idl_type_factory: IdlTypeFactory that created all instances of
IdlType.
report_error: A callback that will be invoked when an error occurs
......@@ -64,12 +62,10 @@ class IdlCompiler(object):
"""
assert isinstance(ir_map, IRMap)
assert isinstance(ref_to_idl_def_factory, RefByIdFactory)
assert isinstance(ref_to_idl_type_factory, RefByIdFactory)
assert isinstance(idl_type_factory, IdlTypeFactory)
assert callable(report_error)
self._ir_map = ir_map
self._ref_to_idl_def_factory = ref_to_idl_def_factory
self._ref_to_idl_type_factory = ref_to_idl_type_factory
self._idl_type_factory = idl_type_factory
self._report_error = report_error
self._db = DatabaseBody()
......@@ -415,7 +411,7 @@ class IdlCompiler(object):
assert False
ref.set_target_object(idl_type)
self._ref_to_idl_type_factory.for_each(resolve)
self._idl_type_factory.for_each_reference(resolve)
def _create_public_unions(self):
all_union_types = [] # all instances of UnionType
......
......@@ -11,8 +11,8 @@ from .composition_parts import WithDebugInfo
from .composition_parts import WithExtendedAttributes
from .composition_parts import WithIdentifier
from .extended_attribute import ExtendedAttributes
from .reference import Proxy
from .reference import RefById
from .reference import RefByIdFactory
from .typedef import Typedef
from .user_defined_type import UserDefinedType
......@@ -47,6 +47,13 @@ class IdlTypeFactory(object):
def __init__(self):
self._idl_types = []
# Factory to initialize instances of ReferenceType.
attrs_to_be_proxied = (
set(RefById.get_all_attributes(IdlType)).difference(
# attributes not to be proxied
set(('debug_info', 'extended_attributes', 'is_optional'))))
self._ref_by_id_factory = RefByIdFactory(
target_attrs_with_priority=attrs_to_be_proxied)
# |_is_frozen| is initially False and you can create new instances of
# IdlType. The first invocation of |for_each| freezes the factory and
# you can no longer create a new instance of IdlType.
......@@ -68,10 +75,26 @@ class IdlTypeFactory(object):
for idl_type in self._idl_types:
callback(idl_type)
def for_each_reference(self, callback):
"""
Applies |callback| to all the instances of IdlType that is referencing
to another IdlType.
Instantiation of referencing IdlType is no longer possible, but it's
still possible to instantiate other IdlTypes.
Args:
callback: A callable that takes an IdlType as only the argument.
Return value is not used.
"""
self._ref_by_id_factory.for_each(callback)
def simple_type(self, *args, **kwargs):
return self._create(SimpleType, args, kwargs)
def reference_type(self, *args, **kwargs):
assert 'ref_by_id_factory' not in kwargs
kwargs['ref_by_id_factory'] = self._ref_by_id_factory
return self._create(ReferenceType, args, kwargs)
def definition_type(self, *args, **kwargs):
......@@ -525,7 +548,7 @@ class SimpleType(IdlType):
return self._name == 'void'
class ReferenceType(IdlType, WithIdentifier, Proxy):
class ReferenceType(IdlType, RefById):
"""
Represents a type specified with the given identifier.
......@@ -537,28 +560,23 @@ class ReferenceType(IdlType, WithIdentifier, Proxy):
identifier may be resolved to a TypedefType.
"""
_attrs_to_be_proxied = set(Proxy.get_all_attributes(IdlType)).difference(
# attributes not to be proxied
set(('debug_info', 'extended_attributes', 'is_optional')))
def __init__(self,
ref_to_idl_type,
identifier,
is_optional=False,
extended_attributes=None,
debug_info=None,
ref_by_id_factory=None,
pass_key=None):
assert isinstance(ref_to_idl_type, RefById)
assert isinstance(ref_by_id_factory, RefByIdFactory)
IdlType.__init__(
self,
is_optional=is_optional,
extended_attributes=extended_attributes,
debug_info=debug_info,
pass_key=pass_key)
WithIdentifier.__init__(self, ref_to_idl_type.identifier)
Proxy.__init__(
self,
target_object=ref_to_idl_type,
target_attrs_with_priority=ReferenceType._attrs_to_be_proxied)
ref_by_id_factory.init_subclass_instance(
self, identifier=identifier, debug_info=debug_info)
def __eq__(self, other):
return (IdlType.__eq__(self, other)
......
......@@ -31,9 +31,8 @@ from .operation import Operation
from .typedef import Typedef
def load_and_register_idl_definitions(
filepaths, register_ir, create_ref_to_idl_def, create_ref_to_idl_type,
idl_type_factory):
def load_and_register_idl_definitions(filepaths, register_ir,
create_ref_to_idl_def, idl_type_factory):
"""
Reads ASTs from |filepaths| and builds IRs from ASTs.
......@@ -43,8 +42,6 @@ def load_and_register_idl_definitions(
IR.
create_ref_to_idl_def: A callback function that creates a reference
to an IDL definition from the given identifier.
create_ref_to_idl_type: A callback function that creates a reference
to an IdlType from the given identifier.
idl_type_factory: All IdlType instances will be created through this
factory.
"""
......@@ -56,7 +53,6 @@ def load_and_register_idl_definitions(
builder = _IRBuilder(
component=component,
create_ref_to_idl_def=create_ref_to_idl_def,
create_ref_to_idl_type=create_ref_to_idl_type,
idl_type_factory=idl_type_factory)
for file_node in asts_per_component:
......@@ -66,25 +62,20 @@ def load_and_register_idl_definitions(
class _IRBuilder(object):
def __init__(self, component, create_ref_to_idl_def,
create_ref_to_idl_type, idl_type_factory):
def __init__(self, component, create_ref_to_idl_def, idl_type_factory):
"""
Args:
component: A Component to which the built IRs are associated.
create_ref_to_idl_def: A callback function that creates a reference
to an IDL definition from the given identifier.
create_ref_to_idl_type: A callback function that creates a reference
to an IdlType from the given identifier.
idl_type_factory: All IdlType instances will be created through this
factory.
"""
assert callable(create_ref_to_idl_def)
assert callable(create_ref_to_idl_type)
assert isinstance(idl_type_factory, IdlTypeFactory)
self._component = component
self._create_ref_to_idl_def = create_ref_to_idl_def
self._create_ref_to_idl_type = create_ref_to_idl_type
self._idl_type_factory = idl_type_factory
def build_top_level_def(self, node):
......@@ -234,8 +225,7 @@ class _IRBuilder(object):
child_nodes) or fallback_extended_attributes
assert len(child_nodes) == 0
return_type = self._idl_type_factory.reference_type(
ref_to_idl_type=self._create_ref_to_idl_type(
interface_identifier))
interface_identifier)
return Constructor.IR(
arguments=arguments,
return_type=return_type,
......@@ -660,8 +650,7 @@ class _IRBuilder(object):
def build_reference_type(node, extended_attributes):
return self._idl_type_factory.reference_type(
ref_to_idl_type=self._create_ref_to_idl_type(
Identifier(node.GetName()), self._build_debug_info(node)),
Identifier(node.GetName()),
is_optional=is_optional,
extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node))
......
......@@ -154,6 +154,8 @@ class RefByIdFactory(object):
def create(self, identifier, debug_info=None):
"""
Creates a new instance of RefById.
Args:
identifier: An identifier to be resolved later.
debug_info: Where the reference is created, which is useful
......@@ -169,6 +171,22 @@ class RefByIdFactory(object):
self._references.append(ref)
return ref
def init_subclass_instance(self, instance, identifier, debug_info=None):
"""
Initializes an instance of a subclass of RefById.
"""
assert type(instance) is not RefById
assert isinstance(instance, RefById)
assert not self._is_frozen
RefById.__init__(
instance,
identifier,
debug_info=debug_info,
target_attrs=self._target_attrs,
target_attrs_with_priority=self._target_attrs_with_priority,
pass_key=_REF_BY_ID_PASS_KEY)
self._references.append(instance)
def for_each(self, callback):
"""
Applies |callback| to all the references created by this factory.
......
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