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

IDL compiler: Implement CallbackFunction

Implements CallbackFunction and FunctionLike.  FunctionLike
will be used as a base class of Operation and Constructor.

Bug: 839389
Change-Id: Iab3f0fe6988aece2e86902c210c0b54c1fd7228e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1741438Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#685119}
parent 51b142e6
...@@ -18,6 +18,7 @@ web_idl/dictionary.py ...@@ -18,6 +18,7 @@ web_idl/dictionary.py
web_idl/enumeration.py web_idl/enumeration.py
web_idl/exposure.py web_idl/exposure.py
web_idl/extended_attribute.py web_idl/extended_attribute.py
web_idl/function_like.py
web_idl/identifier_ir_map.py web_idl/identifier_ir_map.py
web_idl/idl_compiler.py web_idl/idl_compiler.py
web_idl/idl_member.py web_idl/idl_member.py
......
...@@ -27,6 +27,7 @@ web_idl/dictionary.py ...@@ -27,6 +27,7 @@ web_idl/dictionary.py
web_idl/enumeration.py web_idl/enumeration.py
web_idl/exposure.py web_idl/exposure.py
web_idl/extended_attribute.py web_idl/extended_attribute.py
web_idl/function_like.py
web_idl/identifier_ir_map.py web_idl/identifier_ir_map.py
web_idl/idl_compiler.py web_idl/idl_compiler.py
web_idl/idl_member.py web_idl/idl_member.py
......
...@@ -3,31 +3,20 @@ ...@@ -3,31 +3,20 @@
# found in the LICENSE file. # found in the LICENSE file.
from .composition_parts import WithIdentifier from .composition_parts import WithIdentifier
from .composition_parts import WithExtendedAttributes
from .composition_parts import WithCodeGeneratorInfo
from .composition_parts import WithOwner from .composition_parts import WithOwner
from .idl_type import IdlType from .idl_type import IdlType
from .values import DefaultValue from .values import DefaultValue
class Argument(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, class Argument(WithIdentifier, WithOwner):
WithOwner): class IR(WithIdentifier):
class IR(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo): def __init__(self, identifier, index, idl_type, default_value=None):
def __init__(self,
identifier,
index,
idl_type,
default_value=None,
extended_attributes=None,
code_generator_info=None):
assert isinstance(index, int) assert isinstance(index, int)
assert isinstance(idl_type, IdlType) assert isinstance(idl_type, IdlType)
assert (default_value is None assert (default_value is None
or isinstance(default_value, DefaultValue)) or isinstance(default_value, DefaultValue))
WithIdentifier.__init__(self, identifier) WithIdentifier.__init__(self, identifier)
WithExtendedAttributes.__init__(self, extended_attributes)
WithCodeGeneratorInfo.__init__(self, code_generator_info)
self.index = index self.index = index
self.idl_type = idl_type self.idl_type = idl_type
...@@ -38,46 +27,39 @@ class Argument(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo, ...@@ -38,46 +27,39 @@ class Argument(WithIdentifier, WithExtendedAttributes, WithCodeGeneratorInfo,
identifier=self.identifier, identifier=self.identifier,
index=self.index, index=self.index,
idl_type=self.idl_type, idl_type=self.idl_type,
default_value=self.default_value, default_value=self.default_value)
extended_attributes=self.extended_attributes.make_copy(),
code_generator_info=self.code_generator_info.make_copy()) def __init__(self, ir, owner):
assert isinstance(ir, Argument.IR)
WithIdentifier.__init__(self, ir.identifier)
WithOwner.__init__(self, owner)
self._index = ir.index
self._idl_type = ir.idl_type
self._default_value = ir.default_value
@property
def index(self):
"""Returns the argument index."""
return self._index
@property @property
def idl_type(self): def idl_type(self):
""" """Returns the type of the argument."""
Returns type of this argument. return self._idl_type
@return IdlType
"""
assert False, 'To be implemented'
@property @property
def is_optional(self): def is_optional(self):
""" """Returns True if this is an optional argument."""
Returns True if this argument is optional. return self.idl_type.is_optional
@return bool
"""
assert False, 'To be implemented'
@property @property
def is_variadic(self): def is_variadic(self):
""" """Returns True if this is a variadic argument."""
Returns True if this argument is variadic. return self.idl_type.is_variadic
@return bool
"""
assert False, 'To be implemented'
@property @property
def default_value(self): def default_value(self):
""" """Returns the default value or None."""
Returns the default value if it is specified. Otherwise, None return self._default_value
@return DefaultValue
"""
assert False, 'To be implemented'
@property
def index(self):
"""
Returns its index in an operation's arguments
@return int
"""
assert False, 'To be implemented'
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import exceptions import exceptions
from .function_like import FunctionLike
from .composition_parts import WithCodeGeneratorInfo from .composition_parts import WithCodeGeneratorInfo
from .composition_parts import WithComponent from .composition_parts import WithComponent
from .composition_parts import WithDebugInfo from .composition_parts import WithDebugInfo
...@@ -12,14 +13,16 @@ from .identifier_ir_map import IdentifierIRMap ...@@ -12,14 +13,16 @@ from .identifier_ir_map import IdentifierIRMap
from .user_defined_type import UserDefinedType from .user_defined_type import UserDefinedType
class CallbackFunction(UserDefinedType, WithExtendedAttributes, class CallbackFunction(UserDefinedType, FunctionLike, WithExtendedAttributes,
WithCodeGeneratorInfo, WithComponent, WithDebugInfo): WithCodeGeneratorInfo, WithComponent, WithDebugInfo):
"""https://heycam.github.io/webidl/#idl-callback-functions""" """https://heycam.github.io/webidl/#idl-callback-functions"""
class IR(IdentifierIRMap.IR, WithExtendedAttributes, WithCodeGeneratorInfo, class IR(IdentifierIRMap.IR, FunctionLike.IR, WithExtendedAttributes,
WithComponent, WithDebugInfo): WithCodeGeneratorInfo, WithComponent, WithDebugInfo):
def __init__(self, def __init__(self,
identifier, identifier,
arguments,
return_type,
extended_attributes=None, extended_attributes=None,
code_generator_info=None, code_generator_info=None,
component=None, component=None,
...@@ -28,26 +31,24 @@ class CallbackFunction(UserDefinedType, WithExtendedAttributes, ...@@ -28,26 +31,24 @@ class CallbackFunction(UserDefinedType, WithExtendedAttributes,
self, self,
identifier=identifier, identifier=identifier,
kind=IdentifierIRMap.IR.Kind.CALLBACK_FUNCTION) kind=IdentifierIRMap.IR.Kind.CALLBACK_FUNCTION)
FunctionLike.IR.__init__(
self, arguments=arguments, return_type=return_type)
WithExtendedAttributes.__init__(self, extended_attributes) WithExtendedAttributes.__init__(self, extended_attributes)
WithCodeGeneratorInfo.__init__(self, code_generator_info) WithCodeGeneratorInfo.__init__(self, code_generator_info)
WithComponent.__init__(self, component) WithComponent.__init__(self, component)
WithDebugInfo.__init__(self, debug_info) WithDebugInfo.__init__(self, debug_info)
@property def __init__(self, ir):
def return_type(self): assert isinstance(ir, CallbackFunction.IR)
"""
Returns the type of return value. UserDefinedType.__init__(self, ir.identifier)
@return IdlType FunctionLike.__init__(self, ir)
""" WithExtendedAttributes.__init__(self,
raise exceptions.NotImplementedError() ir.extended_attributes.make_copy())
WithCodeGeneratorInfo.__init__(self,
@property ir.code_generator_info.make_copy())
def arguments(self): WithComponent.__init__(self, components=ir.components)
""" WithDebugInfo.__init__(self, ir.debug_info.make_copy())
Returns a list of arguments.
@return Argument
"""
raise exceptions.NotImplementedError()
# UserDefinedType overrides # UserDefinedType overrides
@property @property
......
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from .argument import Argument
from .idl_type import IdlType
class FunctionLike(object):
class IR(object):
def __init__(self, arguments, return_type):
assert isinstance(arguments, (list, tuple)) and all(
isinstance(arg, Argument.IR) for arg in arguments)
assert isinstance(return_type, IdlType)
self.arguments = list(arguments)
self.return_type = return_type
def __init__(self, ir):
assert isinstance(ir, FunctionLike.IR)
self._arguments = tuple(
[Argument(arg_ir, self) for arg_ir in ir.arguments])
self._return_type = ir.return_type
@property
def arguments(self):
"""Returns a list of arguments."""
return self._arguments
@property
def return_type(self):
"""Returns the return type."""
return self._return_type
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# 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.
from .callback_function import CallbackFunction
from .composition_parts import Identifier from .composition_parts import Identifier
from .database import Database from .database import Database
from .database import DatabaseBody from .database import DatabaseBody
...@@ -201,6 +202,12 @@ class IdlCompiler(object): ...@@ -201,6 +202,12 @@ class IdlCompiler(object):
for ir in dictionary_irs.itervalues(): for ir in dictionary_irs.itervalues():
self._db.register(DatabaseBody.Kind.DICTIONARY, Dictionary(ir)) self._db.register(DatabaseBody.Kind.DICTIONARY, Dictionary(ir))
callback_function_irs = self._ir_map.find_by_kind(
IdentifierIRMap.IR.Kind.CALLBACK_FUNCTION)
for ir in callback_function_irs.itervalues():
self._db.register(DatabaseBody.Kind.CALLBACK_FUNCTION,
CallbackFunction(ir))
typedef_irs = self._ir_map.find_by_kind( typedef_irs = self._ir_map.find_by_kind(
IdentifierIRMap.IR.Kind.TYPEDEF) IdentifierIRMap.IR.Kind.TYPEDEF)
for ir in typedef_irs.itervalues(): for ir in typedef_irs.itervalues():
......
...@@ -104,13 +104,13 @@ class _IRBuilder(object): ...@@ -104,13 +104,13 @@ class _IRBuilder(object):
return self._build_callback_interface(node) return self._build_callback_interface(node)
child_nodes = list(node.GetChildren()) child_nodes = list(node.GetChildren())
extended_attributes = self._take_extended_attributes(child_nodes)
inherited = self._take_inheritance(child_nodes) inherited = self._take_inheritance(child_nodes)
iterable = self._take_iterable(child_nodes) iterable = self._take_iterable(child_nodes)
maplike = self._take_maplike(child_nodes) maplike = self._take_maplike(child_nodes)
setlike = self._take_setlike(child_nodes) setlike = self._take_setlike(child_nodes)
# TODO(peria): Implement stringifier. # TODO(peria): Implement stringifier.
_ = self._take_stringifier(child_nodes) _ = self._take_stringifier(child_nodes)
extended_attributes = self._take_extended_attributes(child_nodes)
members = map(self._build_interface_or_namespace_member, child_nodes) members = map(self._build_interface_or_namespace_member, child_nodes)
attributes = [] attributes = []
...@@ -145,13 +145,12 @@ class _IRBuilder(object): ...@@ -145,13 +145,12 @@ class _IRBuilder(object):
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
def _build_namespace(self, node): def _build_namespace(self, node):
namespace = Namespace.IR( # TODO(peria): Build members and register them in |namespace|
return Namespace.IR(
identifier=Identifier(node.GetName()), identifier=Identifier(node.GetName()),
is_partial=bool(node.GetProperty('PARTIAL')), is_partial=bool(node.GetProperty('PARTIAL')),
component=self._component, component=self._component,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
# TODO(peria): Build members and register them in |namespace|
return namespace
def _build_interface_or_namespace_member(self, node): def _build_interface_or_namespace_member(self, node):
def build_attribute(node): def build_attribute(node):
...@@ -209,8 +208,8 @@ class _IRBuilder(object): ...@@ -209,8 +208,8 @@ class _IRBuilder(object):
def _build_dictionary(self, node): def _build_dictionary(self, node):
child_nodes = list(node.GetChildren()) child_nodes = list(node.GetChildren())
extended_attributes = self._take_extended_attributes(child_nodes)
inherited = self._take_inheritance(child_nodes) inherited = self._take_inheritance(child_nodes)
extended_attributes = self._take_extended_attributes(child_nodes)
own_members = map(self._build_dictionary_member, child_nodes) own_members = map(self._build_dictionary_member, child_nodes)
return Dictionary.IR( return Dictionary.IR(
...@@ -241,48 +240,51 @@ class _IRBuilder(object): ...@@ -241,48 +240,51 @@ class _IRBuilder(object):
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
def _build_callback_interface(self, node): def _build_callback_interface(self, node):
callback_interface = CallbackInterface.IR( assert node.GetProperty('CALLBACK')
# TODO(peria): Build members and register them in |callback_interface|
return CallbackInterface.IR(
identifier=Identifier(node.GetName()), identifier=Identifier(node.GetName()),
component=self._component, component=self._component,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
# TODO(peria): Build members and register them in |callback_interface|
return callback_interface
def _build_callback_function(self, node): def _build_callback_function(self, node):
callback_function = CallbackFunction.IR( child_nodes = list(node.GetChildren())
arguments = self._take_arguments(child_nodes)
return_type = self._take_type(child_nodes)
extended_attributes = self._take_extended_attributes(child_nodes)
assert len(child_nodes) == 0
return CallbackFunction.IR(
identifier=Identifier(node.GetName()), identifier=Identifier(node.GetName()),
arguments=arguments,
return_type=return_type,
extended_attributes=extended_attributes,
component=self._component, component=self._component,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
# TODO(peria): Build members and register them in |callback_function|
return callback_function
def _build_enumeration(self, node): def _build_enumeration(self, node):
enumeration = Enumeration.IR( return Enumeration.IR(
identifier=Identifier(node.GetName()), identifier=Identifier(node.GetName()),
values=[child.GetName() for child in node.GetChildren()], values=[child.GetName() for child in node.GetChildren()],
component=self._component, component=self._component,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
return enumeration
def _build_typedef(self, node): def _build_typedef(self, node):
child_nodes = list(node.GetChildren()) child_nodes = list(node.GetChildren())
idl_type = self._take_type(child_nodes) idl_type = self._take_type(child_nodes)
assert len(child_nodes) == 0 assert len(child_nodes) == 0
typedef = Typedef.IR( return Typedef.IR(
identifier=Identifier(node.GetName()), identifier=Identifier(node.GetName()),
idl_type=idl_type, idl_type=idl_type,
component=self._component, component=self._component,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
return typedef
def _build_includes(self, node): def _build_includes(self, node):
includes = Includes.IR( return Includes.IR(
interface_identifier=Identifier(node.GetName()), interface_identifier=Identifier(node.GetName()),
mixin_identifier=Identifier(node.GetProperty('REFERENCE')), mixin_identifier=Identifier(node.GetProperty('REFERENCE')),
component=self._component, component=self._component,
debug_info=self._build_debug_info(node)) debug_info=self._build_debug_info(node))
return includes
# Helper functions sorted alphabetically # Helper functions sorted alphabetically
...@@ -295,14 +297,17 @@ class _IRBuilder(object): ...@@ -295,14 +297,17 @@ class _IRBuilder(object):
idl_type = self._take_type( idl_type = self._take_type(
child_nodes, is_optional=is_optional, is_variadic=is_variadic) child_nodes, is_optional=is_optional, is_variadic=is_variadic)
default_value = self._take_default_value(child_nodes) default_value = self._take_default_value(child_nodes)
extended_attributes = self._take_extended_attributes(child_nodes) # The parser may place extended attributes on arguments, but they
# should be applied to types.
# TODO(yukishiino): Move the extended attributes on this argument
# into |idl_type|.
_ = self._take_extended_attributes(child_nodes)
assert len(child_nodes) == 0 assert len(child_nodes) == 0
return Argument.IR( return Argument.IR(
identifier=Identifier(node.GetName()), identifier=Identifier(node.GetName()),
index=index, index=index,
idl_type=idl_type, idl_type=idl_type,
default_value=default_value, default_value=default_value)
extended_attributes=extended_attributes)
assert node.GetClass() == 'Arguments' assert node.GetClass() == 'Arguments'
return [ return [
......
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