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): ...@@ -25,7 +25,6 @@ def build_database(filepaths, report_error):
assert callable(report_error) assert callable(report_error)
ir_map = IRMap() ir_map = IRMap()
ref_to_idl_type_factory = RefByIdFactory()
ref_to_idl_def_factory = RefByIdFactory() ref_to_idl_def_factory = RefByIdFactory()
idl_type_factory = IdlTypeFactory() idl_type_factory = IdlTypeFactory()
...@@ -33,13 +32,11 @@ def build_database(filepaths, report_error): ...@@ -33,13 +32,11 @@ def build_database(filepaths, report_error):
filepaths=filepaths, filepaths=filepaths,
register_ir=ir_map.register, register_ir=ir_map.register,
create_ref_to_idl_def=ref_to_idl_def_factory.create, 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) idl_type_factory=idl_type_factory)
compiler = IdlCompiler( compiler = IdlCompiler(
ir_map=ir_map, ir_map=ir_map,
ref_to_idl_def_factory=ref_to_idl_def_factory, 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, idl_type_factory=idl_type_factory,
report_error=report_error) report_error=report_error)
return compiler.build_database() return compiler.build_database()
...@@ -46,15 +46,13 @@ class IdlCompiler(object): ...@@ -46,15 +46,13 @@ class IdlCompiler(object):
Note that an old IR for 'x' remains internally. See IRMap for the details. 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, def __init__(self, ir_map, ref_to_idl_def_factory, idl_type_factory,
idl_type_factory, report_error): report_error):
""" """
Args: Args:
ir_map: IRMap filled with the initial IRs of IDL definitions. ir_map: IRMap filled with the initial IRs of IDL definitions.
ref_to_idl_def_factory: RefByIdFactory that created all references ref_to_idl_def_factory: RefByIdFactory that created all references
to UserDefinedType. to UserDefinedType.
ref_to_idl_type_factory: RefByIdFactory that created all references
to IdlType.
idl_type_factory: IdlTypeFactory that created all instances of idl_type_factory: IdlTypeFactory that created all instances of
IdlType. IdlType.
report_error: A callback that will be invoked when an error occurs report_error: A callback that will be invoked when an error occurs
...@@ -64,12 +62,10 @@ class IdlCompiler(object): ...@@ -64,12 +62,10 @@ class IdlCompiler(object):
""" """
assert isinstance(ir_map, IRMap) assert isinstance(ir_map, IRMap)
assert isinstance(ref_to_idl_def_factory, RefByIdFactory) assert isinstance(ref_to_idl_def_factory, RefByIdFactory)
assert isinstance(ref_to_idl_type_factory, RefByIdFactory)
assert isinstance(idl_type_factory, IdlTypeFactory) assert isinstance(idl_type_factory, IdlTypeFactory)
assert callable(report_error) assert callable(report_error)
self._ir_map = ir_map self._ir_map = ir_map
self._ref_to_idl_def_factory = ref_to_idl_def_factory 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._idl_type_factory = idl_type_factory
self._report_error = report_error self._report_error = report_error
self._db = DatabaseBody() self._db = DatabaseBody()
...@@ -415,7 +411,7 @@ class IdlCompiler(object): ...@@ -415,7 +411,7 @@ class IdlCompiler(object):
assert False assert False
ref.set_target_object(idl_type) 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): def _create_public_unions(self):
all_union_types = [] # all instances of UnionType all_union_types = [] # all instances of UnionType
......
...@@ -11,8 +11,8 @@ from .composition_parts import WithDebugInfo ...@@ -11,8 +11,8 @@ from .composition_parts import WithDebugInfo
from .composition_parts import WithExtendedAttributes from .composition_parts import WithExtendedAttributes
from .composition_parts import WithIdentifier from .composition_parts import WithIdentifier
from .extended_attribute import ExtendedAttributes from .extended_attribute import ExtendedAttributes
from .reference import Proxy
from .reference import RefById from .reference import RefById
from .reference import RefByIdFactory
from .typedef import Typedef from .typedef import Typedef
from .user_defined_type import UserDefinedType from .user_defined_type import UserDefinedType
...@@ -47,6 +47,13 @@ class IdlTypeFactory(object): ...@@ -47,6 +47,13 @@ class IdlTypeFactory(object):
def __init__(self): def __init__(self):
self._idl_types = [] 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 # |_is_frozen| is initially False and you can create new instances of
# IdlType. The first invocation of |for_each| freezes the factory and # IdlType. The first invocation of |for_each| freezes the factory and
# you can no longer create a new instance of IdlType. # you can no longer create a new instance of IdlType.
...@@ -68,10 +75,26 @@ class IdlTypeFactory(object): ...@@ -68,10 +75,26 @@ class IdlTypeFactory(object):
for idl_type in self._idl_types: for idl_type in self._idl_types:
callback(idl_type) 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): def simple_type(self, *args, **kwargs):
return self._create(SimpleType, args, kwargs) return self._create(SimpleType, args, kwargs)
def reference_type(self, *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) return self._create(ReferenceType, args, kwargs)
def definition_type(self, *args, **kwargs): def definition_type(self, *args, **kwargs):
...@@ -525,7 +548,7 @@ class SimpleType(IdlType): ...@@ -525,7 +548,7 @@ class SimpleType(IdlType):
return self._name == 'void' return self._name == 'void'
class ReferenceType(IdlType, WithIdentifier, Proxy): class ReferenceType(IdlType, RefById):
""" """
Represents a type specified with the given identifier. Represents a type specified with the given identifier.
...@@ -537,28 +560,23 @@ class ReferenceType(IdlType, WithIdentifier, Proxy): ...@@ -537,28 +560,23 @@ class ReferenceType(IdlType, WithIdentifier, Proxy):
identifier may be resolved to a TypedefType. 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, def __init__(self,
ref_to_idl_type, identifier,
is_optional=False, is_optional=False,
extended_attributes=None, extended_attributes=None,
debug_info=None, debug_info=None,
ref_by_id_factory=None,
pass_key=None): pass_key=None):
assert isinstance(ref_to_idl_type, RefById) assert isinstance(ref_by_id_factory, RefByIdFactory)
IdlType.__init__( IdlType.__init__(
self, self,
is_optional=is_optional, is_optional=is_optional,
extended_attributes=extended_attributes, extended_attributes=extended_attributes,
debug_info=debug_info, debug_info=debug_info,
pass_key=pass_key) pass_key=pass_key)
WithIdentifier.__init__(self, ref_to_idl_type.identifier) ref_by_id_factory.init_subclass_instance(
Proxy.__init__( self, identifier=identifier, debug_info=debug_info)
self,
target_object=ref_to_idl_type,
target_attrs_with_priority=ReferenceType._attrs_to_be_proxied)
def __eq__(self, other): def __eq__(self, other):
return (IdlType.__eq__(self, other) return (IdlType.__eq__(self, other)
......
...@@ -31,9 +31,8 @@ from .operation import Operation ...@@ -31,9 +31,8 @@ from .operation import Operation
from .typedef import Typedef from .typedef import Typedef
def load_and_register_idl_definitions( def load_and_register_idl_definitions(filepaths, register_ir,
filepaths, register_ir, create_ref_to_idl_def, create_ref_to_idl_type, create_ref_to_idl_def, idl_type_factory):
idl_type_factory):
""" """
Reads ASTs from |filepaths| and builds IRs from ASTs. Reads ASTs from |filepaths| and builds IRs from ASTs.
...@@ -43,8 +42,6 @@ def load_and_register_idl_definitions( ...@@ -43,8 +42,6 @@ def load_and_register_idl_definitions(
IR. IR.
create_ref_to_idl_def: A callback function that creates a reference create_ref_to_idl_def: A callback function that creates a reference
to an IDL definition from the given identifier. 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 idl_type_factory: All IdlType instances will be created through this
factory. factory.
""" """
...@@ -56,7 +53,6 @@ def load_and_register_idl_definitions( ...@@ -56,7 +53,6 @@ def load_and_register_idl_definitions(
builder = _IRBuilder( builder = _IRBuilder(
component=component, component=component,
create_ref_to_idl_def=create_ref_to_idl_def, 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) idl_type_factory=idl_type_factory)
for file_node in asts_per_component: for file_node in asts_per_component:
...@@ -66,25 +62,20 @@ def load_and_register_idl_definitions( ...@@ -66,25 +62,20 @@ def load_and_register_idl_definitions(
class _IRBuilder(object): class _IRBuilder(object):
def __init__(self, component, create_ref_to_idl_def, def __init__(self, component, create_ref_to_idl_def, idl_type_factory):
create_ref_to_idl_type, idl_type_factory):
""" """
Args: Args:
component: A Component to which the built IRs are associated. component: A Component to which the built IRs are associated.
create_ref_to_idl_def: A callback function that creates a reference create_ref_to_idl_def: A callback function that creates a reference
to an IDL definition from the given identifier. 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 idl_type_factory: All IdlType instances will be created through this
factory. factory.
""" """
assert callable(create_ref_to_idl_def) assert callable(create_ref_to_idl_def)
assert callable(create_ref_to_idl_type)
assert isinstance(idl_type_factory, IdlTypeFactory) assert isinstance(idl_type_factory, IdlTypeFactory)
self._component = component self._component = component
self._create_ref_to_idl_def = create_ref_to_idl_def 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 self._idl_type_factory = idl_type_factory
def build_top_level_def(self, node): def build_top_level_def(self, node):
...@@ -234,8 +225,7 @@ class _IRBuilder(object): ...@@ -234,8 +225,7 @@ class _IRBuilder(object):
child_nodes) or fallback_extended_attributes child_nodes) or fallback_extended_attributes
assert len(child_nodes) == 0 assert len(child_nodes) == 0
return_type = self._idl_type_factory.reference_type( 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( return Constructor.IR(
arguments=arguments, arguments=arguments,
return_type=return_type, return_type=return_type,
...@@ -660,8 +650,7 @@ class _IRBuilder(object): ...@@ -660,8 +650,7 @@ class _IRBuilder(object):
def build_reference_type(node, extended_attributes): def build_reference_type(node, extended_attributes):
return self._idl_type_factory.reference_type( return self._idl_type_factory.reference_type(
ref_to_idl_type=self._create_ref_to_idl_type( Identifier(node.GetName()),
Identifier(node.GetName()), self._build_debug_info(node)),
is_optional=is_optional, is_optional=is_optional,
extended_attributes=extended_attributes, extended_attributes=extended_attributes,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
......
...@@ -154,6 +154,8 @@ class RefByIdFactory(object): ...@@ -154,6 +154,8 @@ class RefByIdFactory(object):
def create(self, identifier, debug_info=None): def create(self, identifier, debug_info=None):
""" """
Creates a new instance of RefById.
Args: Args:
identifier: An identifier to be resolved later. identifier: An identifier to be resolved later.
debug_info: Where the reference is created, which is useful debug_info: Where the reference is created, which is useful
...@@ -169,6 +171,22 @@ class RefByIdFactory(object): ...@@ -169,6 +171,22 @@ class RefByIdFactory(object):
self._references.append(ref) self._references.append(ref)
return 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): def for_each(self, callback):
""" """
Applies |callback| to all the references created by this factory. 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