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

bind-gen: Implement property installation (1 of N)

Bug: 839389
Change-Id: Ib07f7d22f6b5d64e7d3e83e16c38ae304f34d7f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1887210Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711240}
parent cdc7cc8b
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
import copy import copy
from blinkbuild.name_style_converter import NameStyleConverter
class CodeGenerationContext(object): class CodeGenerationContext(object):
""" """
...@@ -15,7 +17,7 @@ class CodeGenerationContext(object): ...@@ -15,7 +17,7 @@ class CodeGenerationContext(object):
as "${interface}". as "${interface}".
""" """
# "world" attribute values # "for_world" attribute values
MAIN_WORLD = "main" MAIN_WORLD = "main"
ALL_WORLDS = "all" ALL_WORLDS = "all"
...@@ -32,8 +34,11 @@ class CodeGenerationContext(object): ...@@ -32,8 +34,11 @@ class CodeGenerationContext(object):
"callback_function": None, "callback_function": None,
"callback_interface": None, "callback_interface": None,
"dictionary": None, "dictionary": None,
"enumeration": None,
"interface": None, "interface": None,
"namespace": None, "namespace": None,
"typedef": None,
"union": None,
# Class-member-ish definition # Class-member-ish definition
"attribute": None, "attribute": None,
...@@ -47,14 +52,20 @@ class CodeGenerationContext(object): ...@@ -47,14 +52,20 @@ class CodeGenerationContext(object):
"operation_group": None, "operation_group": None,
# Main world or all worlds # Main world or all worlds
"world": cls.ALL_WORLDS, "for_world": cls.ALL_WORLDS,
} }
# List of computational attribute names # List of computational attribute names
cls._computational_attrs = ( cls._computational_attrs = (
"class_like", "class_like",
"function_like",
"idl_definition",
"is_return_by_argument",
"may_throw_exception",
"member_like", "member_like",
"property_", "property_",
"return_type",
"v8_class",
) )
# Define public readonly properties of this class. # Define public readonly properties of this class.
...@@ -137,6 +148,12 @@ class CodeGenerationContext(object): ...@@ -137,6 +148,12 @@ class CodeGenerationContext(object):
def function_like(self): def function_like(self):
return (self.callback_function or self.constructor or self.operation) return (self.callback_function or self.constructor or self.operation)
@property
def idl_definition(self):
return (self.callback_function or self.callback_interface
or self.dictionary or self.enumeration or self.interface
or self.namespace or self.typedef or self.union)
@property @property
def is_return_by_argument(self): def is_return_by_argument(self):
if self.return_type is None: if self.return_type is None:
...@@ -175,5 +192,13 @@ class CodeGenerationContext(object): ...@@ -175,5 +192,13 @@ class CodeGenerationContext(object):
return self.operation.return_type return self.operation.return_type
return None return None
@property
def v8_class(self):
if not self.idl_definition:
return None
return "V8{}".format(
NameStyleConverter(
self.idl_definition.identifier).to_upper_camel_case())
CodeGenerationContext.init() CodeGenerationContext.init()
...@@ -30,7 +30,7 @@ def _upper_camel_case(name): ...@@ -30,7 +30,7 @@ def _upper_camel_case(name):
return NameStyleConverter(name).to_upper_camel_case() return NameStyleConverter(name).to_upper_camel_case()
def bind_common_local_vars(code_node, cg_context): def bind_callback_local_vars(code_node, cg_context):
assert isinstance(code_node, SymbolScopeNode) assert isinstance(code_node, SymbolScopeNode)
assert isinstance(cg_context, CodeGenerationContext) assert isinstance(cg_context, CodeGenerationContext)
...@@ -253,7 +253,7 @@ def bind_v8_set_return_value(code_node, cg_context): ...@@ -253,7 +253,7 @@ def bind_v8_set_return_value(code_node, cg_context):
# Render a SymbolNode |return_value| discarding the content text, and # Render a SymbolNode |return_value| discarding the content text, and
# let a symbol definition be added. # let a symbol definition be added.
pattern = "<% str(return_value) %>" pattern = "<% str(return_value) %>"
elif (cg_context.world == cg_context.MAIN_WORLD elif (cg_context.for_world == cg_context.MAIN_WORLD
and cg_context.return_type.unwrap().is_interface): and cg_context.return_type.unwrap().is_interface):
_1 = "V8SetReturnValueForMainWorld" _1 = "V8SetReturnValueForMainWorld"
elif cg_context.return_type.unwrap().is_interface: elif cg_context.return_type.unwrap().is_interface:
...@@ -281,7 +281,7 @@ def make_attribute_get_def(cg_context): ...@@ -281,7 +281,7 @@ def make_attribute_get_def(cg_context):
body.add_template_vars(cg_context.template_bindings()) body.add_template_vars(cg_context.template_bindings())
binders = [ binders = [
bind_common_local_vars, bind_callback_local_vars,
bind_blink_api_arguments, bind_blink_api_arguments,
bind_blink_api_call, bind_blink_api_call,
bind_return_value, bind_return_value,
...@@ -313,7 +313,7 @@ def make_operation_def(cg_context): ...@@ -313,7 +313,7 @@ def make_operation_def(cg_context):
body.add_template_vars(cg_context.template_bindings()) body.add_template_vars(cg_context.template_bindings())
binders = [ binders = [
bind_common_local_vars, bind_callback_local_vars,
bind_blink_api_arguments, bind_blink_api_arguments,
bind_blink_api_call, bind_blink_api_call,
bind_return_value, bind_return_value,
...@@ -329,6 +329,85 @@ def make_operation_def(cg_context): ...@@ -329,6 +329,85 @@ def make_operation_def(cg_context):
return func_def return func_def
def bind_template_installer_local_vars(code_node, cg_context):
assert isinstance(code_node, SymbolScopeNode)
assert isinstance(cg_context, CodeGenerationContext)
S = SymbolNode
local_vars = []
local_vars.extend([
S("instance_template",
("v8::Local<v8::ObjectTemplate> ${instance_template} = "
"${interface_template}->InstanceTemplate();")),
S("prototype_template",
("v8::Local<v8::ObjectTemplate> ${prototype_template} = "
"${interface_template}->PrototypeTemplate();")),
S("signature",
("v8::Local<v8::Signature> ${signature} = "
"v8::Signature::New(${isolate}, ${interface_template});")),
S("wrapper_type_info",
("const WrapperTypeInfo* const ${wrapper_type_info} = "
"${v8_class}::GetWrapperTypeInfo();")),
])
pattern = (
"v8::Local<v8::FunctionTemplate> ${parent_interface_template}{_1};")
_1 = (" = ${wrapper_type_info}->parent_class->dom_template_function"
"(${isolate}, ${world})")
if not cg_context.class_like.inherited:
_1 = ""
local_vars.append(S("parent_interface_template", _format(pattern, _1=_1)))
code_node.register_code_symbols(local_vars)
def make_install_interface_template_def(cg_context):
assert isinstance(cg_context, CodeGenerationContext)
L = LiteralNode
T = TextNode
func_def = FunctionDefinitionNode(
name=L("InstallInterfaceTemplate"),
arg_decls=[
L("v8::Isolate* isolate"),
L("const DOMWrapperWorld& world"),
L("v8::Local<v8::FunctionTemplate> interface_template"),
],
return_type=L("void"))
body = func_def.body
body.add_template_var("isolate", "isolate")
body.add_template_var("world", "world")
body.add_template_var("interface_template", "interface_template")
body.add_template_vars(cg_context.template_bindings())
binders = [
bind_template_installer_local_vars,
]
for bind in binders:
bind(body, cg_context)
body.extend([
T("V8DOMConfiguration::InitializeDOMInterfaceTemplate("
"${isolate}, ${interface_template}, "
"${wrapper_type_info}->interface_name, ${parent_interface_template}, "
"kV8DefaultWrapperInternalFieldCount);"),
])
if cg_context.class_like.constructor_groups:
body.extend([
T("${interface_template}->SetCallHandler(ConstructorCallback);"),
T("${interface_template}->SetLength("
"${class_like.constructor_groups[0]"
".min_num_of_required_arguments});"),
])
return func_def
def run_example(web_idl_database, output_dirs): def run_example(web_idl_database, output_dirs):
renderer = MakoRenderer() renderer = MakoRenderer()
...@@ -340,9 +419,11 @@ def run_example(web_idl_database, output_dirs): ...@@ -340,9 +419,11 @@ def run_example(web_idl_database, output_dirs):
cg_context = CodeGenerationContext(namespace=namespace) cg_context = CodeGenerationContext(namespace=namespace)
root_node = SymbolScopeNode(separator_last="\n", renderer=renderer) root_node = SymbolScopeNode(separator_last="\n", renderer=renderer)
for attribute in namespace.attributes: for attribute in namespace.attributes:
root_node.append( root_node.append(
make_attribute_get_def(cg_context.make_copy(attribute=attribute))) make_attribute_get_def(cg_context.make_copy(attribute=attribute)))
for operation_group in namespace.operation_groups: for operation_group in namespace.operation_groups:
for operation in operation_group: for operation in operation_group:
root_node.append( root_node.append(
...@@ -350,6 +431,8 @@ def run_example(web_idl_database, output_dirs): ...@@ -350,6 +431,8 @@ def run_example(web_idl_database, output_dirs):
cg_context.make_copy( cg_context.make_copy(
operation_group=operation_group, operation=operation))) operation_group=operation_group, operation=operation)))
root_node.append(make_install_interface_template_def(cg_context))
prev = '' prev = ''
current = str(root_node) current = str(root_node)
while current != prev: while current != prev:
......
...@@ -44,3 +44,10 @@ class FunctionLike(WithIdentifier): ...@@ -44,3 +44,10 @@ class FunctionLike(WithIdentifier):
def is_static(self): def is_static(self):
"""Returns True if this is a static function.""" """Returns True if this is a static function."""
return self._is_static return self._is_static
@property
def num_of_required_arguments(self):
"""Returns the number of required arguments."""
return len(
filter(lambda arg: not (arg.is_optional or arg.is_variadic),
self.arguments))
...@@ -99,11 +99,31 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo, ...@@ -99,11 +99,31 @@ class Namespace(UserDefinedType, WithExtendedAttributes, WithCodeGeneratorInfo,
owner=self) for operation_group_ir in ir.operation_groups owner=self) for operation_group_ir in ir.operation_groups
]) ])
@property
def inherited(self):
"""Returns the inherited namespace or None."""
return None
@property @property
def attributes(self): def attributes(self):
"""Returns attributes.""" """Returns attributes."""
return self._attributes return self._attributes
@property
def constants(self):
"""Returns constants."""
return ()
@property
def constructors(self):
"""Returns constructors."""
return ()
@property
def constructor_groups(self):
"""Returns groups of constructors."""
return ()
@property @property
def operations(self): def operations(self):
"""Returns operations.""" """Returns operations."""
......
...@@ -48,3 +48,11 @@ class OverloadGroup(WithIdentifier): ...@@ -48,3 +48,11 @@ class OverloadGroup(WithIdentifier):
@property @property
def is_static(self): def is_static(self):
return self._is_static return self._is_static
@property
def min_num_of_required_arguments(self):
"""
Returns the minimum number of required arguments of overloaded
functions.
"""
return min(map(lambda func: func.num_of_required_arguments, self))
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