Commit 58eba6b0 authored by Yuki Shiino's avatar Yuki Shiino Committed by Chromium LUCI CQ

bind-gen: Implement IDL union (2 of N)

idl_type.py
- Adds new_union_definition_object to help implement NewUnion.

blink_v8_bridge.py
- Adds member_ref_t to represent an input/output type to/from
  a member variable.  Example)
    member_ref_t func(member_ref_t new_value) {
      member_var_ = new_value;
      return member_var_;
    }
- Adds clear_member_var_expr to clear the content of a member
  variable.

These will be used in https://crrev.com/c/2522861 .

Bug: 839389
Change-Id: I738f5a3a18acbbcd09ff4e2fd6b235a8845d43ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2563520Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832311}
parent d04e4609
...@@ -49,17 +49,19 @@ def v8_bridge_class_name(idl_definition): ...@@ -49,17 +49,19 @@ def v8_bridge_class_name(idl_definition):
return "V8{}".format(idl_definition.identifier) return "V8{}".format(idl_definition.identifier)
def blink_type_info(idl_type): def blink_type_info(idl_type, use_new_union=False):
""" """
Returns the types of Blink implementation corresponding to the given IDL Returns the types of Blink implementation corresponding to the given IDL
type. The returned object has the following attributes. type. The returned object has the following attributes.
member_t: The type of a member variable. E.g. T => Member<T>
ref_t: The type of a local variable that references to an already-existing ref_t: The type of a local variable that references to an already-existing
value. E.g. String => String& value. E.g. String => String&
const_ref_t: A const-qualified reference type. const_ref_t: A const-qualified reference type.
value_t: The type of a variable that behaves as a value. E.g. String => value_t: The type of a variable that behaves as a value. E.g. String =>
String String
member_t: The type of a member variable. E.g. T => Member<T>
member_ref_t: The type used for input to and output from a member
variable. E.g. T* for Member<T> and const String& for String.
has_null_value: True if the Blink implementation type can represent IDL has_null_value: True if the Blink implementation type can represent IDL
null value by itself without use of base::Optional<T>. null value by itself without use of base::Optional<T>.
""" """
...@@ -72,28 +74,38 @@ def blink_type_info(idl_type): ...@@ -72,28 +74,38 @@ def blink_type_info(idl_type):
ref_fmt="{}", ref_fmt="{}",
const_ref_fmt="const {}", const_ref_fmt="const {}",
value_fmt="{}", value_fmt="{}",
has_null_value=False): has_null_value=False,
clear_member_var_fmt="{}.Clear()"):
self.typename = typename self.typename = typename
self.member_t = member_fmt.format(typename) self.is_gc_type = is_gc_type(idl_type)
self.ref_t = ref_fmt.format(typename) self.ref_t = ref_fmt.format(typename)
self.const_ref_t = const_ref_fmt.format(typename) self.const_ref_t = const_ref_fmt.format(typename)
self.value_t = value_fmt.format(typename) self.value_t = value_fmt.format(typename)
# Whether Blink impl type can represent IDL null or not. self.member_t = member_fmt.format(typename)
self.member_ref_t = (self.ref_t
if self.is_gc_type else self.const_ref_t)
self.has_null_value = has_null_value self.has_null_value = has_null_value
self._clear_member_var_fmt = clear_member_var_fmt
def clear_member_var_expr(self, var_name):
"""Returns an expression to reset the given member variable."""
return self._clear_member_var_fmt.format(var_name)
def is_gc_type(idl_type): def is_gc_type(idl_type):
idl_type = idl_type.unwrap() idl_type = idl_type.unwrap()
return bool(idl_type.type_definition_object return bool(
and not idl_type.is_enumeration) idl_type.is_buffer_source_type or
(idl_type.type_definition_object and not idl_type.is_enumeration)
or (idl_type.new_union_definition_object and use_new_union))
def vector_element_type(idl_type): def vector_element_type(idl_type):
# Add |Member<T>| explicitly so that the complete type definition of # Use |Member<T>| explicitly so that the complete type definition of
# |T| will not be required. # |T| will not be required.
typename = blink_type_info(idl_type).typename type_info = blink_type_info(idl_type)
if is_gc_type(idl_type): if type_info.is_gc_type:
return "Member<{}>".format(typename) return type_info.member_t
else: else:
return typename return type_info.typename
real_type = idl_type.unwrap(typedef=True) real_type = idl_type.unwrap(typedef=True)
...@@ -113,15 +125,16 @@ def blink_type_info(idl_type): ...@@ -113,15 +125,16 @@ def blink_type_info(idl_type):
"double": "double", "double": "double",
"unrestricted double": "double", "unrestricted double": "double",
} }
return TypeInfo( return TypeInfo(cxx_type[real_type.keyword_typename],
cxx_type[real_type.keyword_typename], const_ref_fmt="{}") const_ref_fmt="{}",
clear_member_var_fmt="{} = 0")
if real_type.is_string: if real_type.is_string:
return TypeInfo( return TypeInfo("String",
"String", ref_fmt="{}&",
ref_fmt="{}&", const_ref_fmt="const {}&",
const_ref_fmt="const {}&", has_null_value=True,
has_null_value=True) clear_member_var_fmt="{} = String()")
if real_type.is_array_buffer: if real_type.is_array_buffer:
assert "AllowShared" not in real_type.extended_attributes assert "AllowShared" not in real_type.extended_attributes
...@@ -168,7 +181,7 @@ def blink_type_info(idl_type): ...@@ -168,7 +181,7 @@ def blink_type_info(idl_type):
if real_type.type_definition_object: if real_type.type_definition_object:
blink_impl_type = blink_class_name(real_type.type_definition_object) blink_impl_type = blink_class_name(real_type.type_definition_object)
if real_type.is_enumeration: if real_type.is_enumeration:
return TypeInfo(blink_impl_type) return TypeInfo(blink_impl_type, clear_member_var_fmt="")
return TypeInfo( return TypeInfo(
blink_impl_type, blink_impl_type,
member_fmt="Member<{}>", member_fmt="Member<{}>",
...@@ -181,18 +194,34 @@ def blink_type_info(idl_type): ...@@ -181,18 +194,34 @@ def blink_type_info(idl_type):
or real_type.is_variadic): or real_type.is_variadic):
typename = "VectorOf<{}>".format( typename = "VectorOf<{}>".format(
vector_element_type(real_type.element_type)) vector_element_type(real_type.element_type))
return TypeInfo(typename, ref_fmt="{}&", const_ref_fmt="const {}&") return TypeInfo(typename,
ref_fmt="{}&",
const_ref_fmt="const {}&",
clear_member_var_fmt="{}.clear()")
if real_type.is_record: if real_type.is_record:
typename = "VectorOfPairs<{}, {}>".format( typename = "VectorOfPairs<{}, {}>".format(
vector_element_type(real_type.key_type), vector_element_type(real_type.key_type),
vector_element_type(real_type.value_type)) vector_element_type(real_type.value_type))
return TypeInfo(typename, ref_fmt="{}&", const_ref_fmt="const {}&") return TypeInfo(typename,
ref_fmt="{}&",
const_ref_fmt="const {}&",
clear_member_var_fmt="{}.clear()")
if real_type.is_promise: if real_type.is_promise:
return TypeInfo( return TypeInfo(
"ScriptPromise", ref_fmt="{}&", const_ref_fmt="const {}&") "ScriptPromise", ref_fmt="{}&", const_ref_fmt="const {}&")
if real_type.is_union and use_new_union:
blink_impl_type = blink_class_name(
real_type.new_union_definition_object)
return TypeInfo(blink_impl_type,
member_fmt="Member<{}>",
ref_fmt="{}*",
const_ref_fmt="const {}*",
value_fmt="{}*",
has_null_value=False)
if real_type.is_union: if real_type.is_union:
blink_impl_type = blink_class_name(real_type.union_definition_object) blink_impl_type = blink_class_name(real_type.union_definition_object)
return TypeInfo( return TypeInfo(
...@@ -205,10 +234,10 @@ def blink_type_info(idl_type): ...@@ -205,10 +234,10 @@ def blink_type_info(idl_type):
inner_type = blink_type_info(real_type.inner_type) inner_type = blink_type_info(real_type.inner_type)
if inner_type.has_null_value: if inner_type.has_null_value:
return inner_type return inner_type
return TypeInfo( return TypeInfo("base::Optional<{}>".format(inner_type.value_t),
"base::Optional<{}>".format(inner_type.value_t), ref_fmt="{}&",
ref_fmt="{}&", const_ref_fmt="const {}&",
const_ref_fmt="const {}&") clear_member_var_fmt="{}.reset()")
assert False, "Unknown type: {}".format(idl_type.syntactic_form) assert False, "Unknown type: {}".format(idl_type.syntactic_form)
......
...@@ -561,6 +561,10 @@ class IdlType(WithExtendedAttributes, WithDebugInfo): ...@@ -561,6 +561,10 @@ class IdlType(WithExtendedAttributes, WithDebugInfo):
""" """
return None return None
@property
def new_union_definition_object(self):
return None
@property @property
def union_definition_object(self): def union_definition_object(self):
""" """
...@@ -1149,6 +1153,7 @@ class UnionType(IdlType): ...@@ -1149,6 +1153,7 @@ class UnionType(IdlType):
debug_info=debug_info, debug_info=debug_info,
pass_key=pass_key) pass_key=pass_key)
self._member_types = tuple(member_types) self._member_types = tuple(member_types)
self._new_union_definition_object = None
self._union_definition_object = None self._union_definition_object = None
def __eq__(self, other): def __eq__(self, other):
...@@ -1222,6 +1227,17 @@ class UnionType(IdlType): ...@@ -1222,6 +1227,17 @@ class UnionType(IdlType):
return set(flatten(self)) return set(flatten(self))
@property
def new_union_definition_object(self):
return self._new_union_definition_object
def set_new_union_definition_object(self, union_definition_object):
# In Python2, we need to avoid circular imports.
from .union import NewUnion
assert isinstance(union_definition_object, NewUnion)
assert self._new_union_definition_object is None
self._new_union_definition_object = union_definition_object
@property @property
def union_definition_object(self): def union_definition_object(self):
return self._union_definition_object return self._union_definition_object
......
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