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 @@
import copy
from blinkbuild.name_style_converter import NameStyleConverter
class CodeGenerationContext(object):
"""
......@@ -15,7 +17,7 @@ class CodeGenerationContext(object):
as "${interface}".
"""
# "world" attribute values
# "for_world" attribute values
MAIN_WORLD = "main"
ALL_WORLDS = "all"
......@@ -32,8 +34,11 @@ class CodeGenerationContext(object):
"callback_function": None,
"callback_interface": None,
"dictionary": None,
"enumeration": None,
"interface": None,
"namespace": None,
"typedef": None,
"union": None,
# Class-member-ish definition
"attribute": None,
......@@ -47,14 +52,20 @@ class CodeGenerationContext(object):
"operation_group": None,
# Main world or all worlds
"world": cls.ALL_WORLDS,
"for_world": cls.ALL_WORLDS,
}
# List of computational attribute names
cls._computational_attrs = (
"class_like",
"function_like",
"idl_definition",
"is_return_by_argument",
"may_throw_exception",
"member_like",
"property_",
"return_type",
"v8_class",
)
# Define public readonly properties of this class.
......@@ -137,6 +148,12 @@ class CodeGenerationContext(object):
def function_like(self):
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
def is_return_by_argument(self):
if self.return_type is None:
......@@ -175,5 +192,13 @@ class CodeGenerationContext(object):
return self.operation.return_type
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()
......@@ -30,7 +30,7 @@ def _upper_camel_case(name):
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(cg_context, CodeGenerationContext)
......@@ -253,7 +253,7 @@ def bind_v8_set_return_value(code_node, cg_context):
# Render a SymbolNode |return_value| discarding the content text, and
# let a symbol definition be added.
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):
_1 = "V8SetReturnValueForMainWorld"
elif cg_context.return_type.unwrap().is_interface:
......@@ -281,7 +281,7 @@ def make_attribute_get_def(cg_context):
body.add_template_vars(cg_context.template_bindings())
binders = [
bind_common_local_vars,
bind_callback_local_vars,
bind_blink_api_arguments,
bind_blink_api_call,
bind_return_value,
......@@ -313,7 +313,7 @@ def make_operation_def(cg_context):
body.add_template_vars(cg_context.template_bindings())
binders = [
bind_common_local_vars,
bind_callback_local_vars,
bind_blink_api_arguments,
bind_blink_api_call,
bind_return_value,
......@@ -329,6 +329,85 @@ def make_operation_def(cg_context):
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):
renderer = MakoRenderer()
......@@ -340,9 +419,11 @@ def run_example(web_idl_database, output_dirs):
cg_context = CodeGenerationContext(namespace=namespace)
root_node = SymbolScopeNode(separator_last="\n", renderer=renderer)
for attribute in namespace.attributes:
root_node.append(
make_attribute_get_def(cg_context.make_copy(attribute=attribute)))
for operation_group in namespace.operation_groups:
for operation in operation_group:
root_node.append(
......@@ -350,6 +431,8 @@ def run_example(web_idl_database, output_dirs):
cg_context.make_copy(
operation_group=operation_group, operation=operation)))
root_node.append(make_install_interface_template_def(cg_context))
prev = ''
current = str(root_node)
while current != prev:
......
......@@ -44,3 +44,10 @@ class FunctionLike(WithIdentifier):
def is_static(self):
"""Returns True if this is a static function."""
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,
owner=self) for operation_group_ir in ir.operation_groups
])
@property
def inherited(self):
"""Returns the inherited namespace or None."""
return None
@property
def attributes(self):
"""Returns 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
def operations(self):
"""Returns operations."""
......
......@@ -48,3 +48,11 @@ class OverloadGroup(WithIdentifier):
@property
def is_static(self):
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