Commit 98ce8e83 authored by Hitoshi Yoshida's avatar Hitoshi Yoshida Committed by Commit Bot

IDL compiler: Make null and undefined distinguishable partially

This CL makes null and undefined distinguishable for dictionary
members whose type is a nullable interface.

It changes Blink-side expectation about dict->hasFoo(), if
a dictionary member `foo` is in the case. Before this CL,
dict->hasFoo() means dict->foo() does not return null pointers,
but after this CL, dict->foo() can returns nullptr.


Bug: 855968
Change-Id: I4dfddf0ae79703a69294aa627cff86f5e7c59252
Reviewed-on: https://chromium-review.googlesource.com/1113176Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Hitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571009}
parent 8e75c95f
......@@ -211,8 +211,16 @@ def member_impl_context(member, interfaces_info, header_includes,
idl_type = unwrap_nullable_if_needed(member.idl_type)
cpp_name = to_snake_case(v8_utilities.cpp_name(member))
# In most cases, we don't have to distinguish `null` and `not present`,
# and use null-states (e.g. nullptr, foo.IsUndefinedOrNull()) to show such
# states for some types for memory usage and performance.
# For types whose |has_explicit_presence| is True, we provide explicit
# states of presence.
has_explicit_presence = (
member.idl_type.is_nullable and member.idl_type.inner_type.is_interface_type)
nullable_indicator_name = None
if not idl_type.cpp_type_has_null_value:
if not idl_type.cpp_type_has_null_value or has_explicit_presence:
nullable_indicator_name = 'has_' + cpp_name + '_'
def has_method_expression():
......@@ -229,8 +237,9 @@ def member_impl_context(member, interfaces_info, header_includes,
return '%s_' % cpp_name
cpp_default_value = None
if member.default_value and not member.default_value.is_null:
cpp_default_value = idl_type.literal_cpp_value(member.default_value)
if member.default_value:
if not member.default_value.is_null or has_explicit_presence:
cpp_default_value = idl_type.literal_cpp_value(member.default_value)
forward_decl_name = idl_type.impl_forward_declaration_name
if forward_decl_name:
......@@ -252,6 +261,7 @@ def member_impl_context(member, interfaces_info, header_includes,
return {
'cpp_default_value': cpp_default_value,
'cpp_name': cpp_name,
'has_explicit_presence': has_explicit_presence,
'getter_expression': cpp_name + '_',
'getter_name': getter_name_for_dictionary_member(member),
'has_method_expression': has_method_expression(),
......
......@@ -1118,8 +1118,7 @@ def cpp_type_has_null_value(idl_type):
# - String types (String/AtomicString) represent null as a null string,
# i.e. one for which String::IsNull() returns true.
# - Enum types, as they are implemented as Strings.
# - Interface types (raw pointer or RefPtr) represent null as
# a null pointer.
# - Interface types (raw pointer) represent null as a null pointer.
# - Union types, as thier container classes can represent null value.
# - 'Object' and 'any' type. We use ScriptValue for object type.
return (idl_type.is_string_type
......
......@@ -13,7 +13,11 @@ namespace blink {
{# Constructor #}
{{cpp_class}}::{{cpp_class}}() {
{% for member in members if member.cpp_default_value %}
{% if member.is_default_value_null and member.null_setter_name %}
{{member.null_setter_name}}();
{% else %}
{{member.setter_name}}({{member.cpp_default_value}});
{% endif %}
{% endfor %}
}
......
......@@ -27,7 +27,7 @@ class {{exported}}{{cpp_class}}{% if parent_cpp_class %} : public {{parent_cpp_c
{% for member in members %}
bool {{member.has_method_name}}() const { return {{member.has_method_expression}}; }
{{member.rvalue_cpp_type}} {{member.getter_name}}() const {
{% if member.nullable_indicator_name %}
{% if member.nullable_indicator_name and not member.has_explicit_presence %}
DCHECK({{member.nullable_indicator_name}});
{% endif %}
return {{member.getter_expression}};
......
......@@ -5,9 +5,13 @@ void {{cpp_class}}::{{member.setter_name}}({{member.rvalue_cpp_type}} value) {
{{member.nullable_indicator_name}} = true;
{% endif %}
}
{% if member.null_setter_name %}
void {{cpp_class}}::{{member.null_setter_name}}() {
{% if member.nullable_indicator_name %}
{% if member.has_explicit_presence %}
{{member.cpp_name}}_ = {{member.member_cpp_type}}();
{{member.nullable_indicator_name}} = false;
{% elif member.nullable_indicator_name %}
{{member.nullable_indicator_name}} = false;
{% else %}
{{member.cpp_name}}_ = {{member.member_cpp_type}}();
......
......@@ -106,6 +106,7 @@ void TestDictionary::setObjectMember(ScriptValue value) {
void TestDictionary::setObjectOrNullMember(ScriptValue value) {
object_or_null_member_ = value;
}
void TestDictionary::setObjectOrNullMemberToNull() {
object_or_null_member_ = ScriptValue();
}
......
......@@ -139,7 +139,7 @@ class CORE_EXPORT TestDictionary : public IDLDictionaryBase {
}
void setDoubleOrStringSequenceMember(const HeapVector<DoubleOrString>&);
bool hasElementOrNullMember() const { return element_or_null_member_; }
bool hasElementOrNullMember() const { return has_element_or_null_member_; }
Element* elementOrNullMember() const {
return element_or_null_member_;
}
......@@ -339,7 +339,7 @@ class CORE_EXPORT TestDictionary : public IDLDictionaryBase {
}
inline void setTestInterfaceMember(TestInterfaceImplementation*);
bool hasTestInterfaceOrNullMember() const { return test_interface_or_null_member_; }
bool hasTestInterfaceOrNullMember() const { return has_test_interface_or_null_member_; }
TestInterfaceImplementation* testInterfaceOrNullMember() const {
return test_interface_or_null_member_;
}
......@@ -432,6 +432,7 @@ class CORE_EXPORT TestDictionary : public IDLDictionaryBase {
bool has_double_or_null_record_member_ = false;
bool has_double_or_null_sequence_member_ = false;
bool has_double_or_string_sequence_member_ = false;
bool has_element_or_null_member_ = false;
bool has_element_or_null_record_member_ = false;
bool has_element_or_null_sequence_member_ = false;
bool has_enum_sequence_member_ = false;
......@@ -448,6 +449,7 @@ class CORE_EXPORT TestDictionary : public IDLDictionaryBase {
bool has_string_or_null_record_member_ = false;
bool has_string_or_null_sequence_member_ = false;
bool has_string_sequence_member_ = false;
bool has_test_interface_or_null_member_ = false;
bool has_test_interface_sequence_member_ = false;
bool has_test_object_sequence_member_ = false;
bool has_treat_null_as_string_sequence_member_ = false;
......@@ -543,15 +545,19 @@ void TestDictionary::setDoubleOrNullMember(double value) {
double_or_null_member_ = value;
has_double_or_null_member_ = true;
}
void TestDictionary::setDoubleOrNullMemberToNull() {
has_double_or_null_member_ = false;
}
void TestDictionary::setElementOrNullMember(Element* value) {
element_or_null_member_ = value;
has_element_or_null_member_ = true;
}
void TestDictionary::setElementOrNullMemberToNull() {
element_or_null_member_ = Member<Element>();
has_element_or_null_member_ = false;
}
void TestDictionary::setEnumMember(const String& value) {
......@@ -561,6 +567,7 @@ void TestDictionary::setEnumMember(const String& value) {
void TestDictionary::setEnumOrNullMember(const String& value) {
enum_or_null_member_ = value;
}
void TestDictionary::setEnumOrNullMemberToNull() {
enum_or_null_member_ = String();
}
......@@ -611,6 +618,7 @@ void TestDictionary::setStringMember(const String& value) {
void TestDictionary::setStringOrNullMember(const String& value) {
string_or_null_member_ = value;
}
void TestDictionary::setStringOrNullMemberToNull() {
string_or_null_member_ = String();
}
......@@ -621,9 +629,12 @@ void TestDictionary::setTestInterfaceMember(TestInterfaceImplementation* value)
void TestDictionary::setTestInterfaceOrNullMember(TestInterfaceImplementation* value) {
test_interface_or_null_member_ = value;
has_test_interface_or_null_member_ = true;
}
void TestDictionary::setTestInterfaceOrNullMemberToNull() {
test_interface_or_null_member_ = Member<TestInterfaceImplementation>();
has_test_interface_or_null_member_ = false;
}
void TestDictionary::setUint8ArrayMember(NotShared<DOMUint8Array> value) {
......@@ -638,6 +649,7 @@ void TestDictionary::setUnrestrictedDoubleMember(double value) {
void TestDictionary::setUsvStringOrNullMember(const String& value) {
usv_string_or_null_member_ = value;
}
void TestDictionary::setUsvStringOrNullMemberToNull() {
usv_string_or_null_member_ = String();
}
......
......@@ -1025,7 +1025,7 @@ void CanvasRenderingContext2D::addHitRegion(const HitRegionOptions& options,
return;
}
Path hit_region_path = options.hasPath() ? options.path()->GetPath() : path_;
Path hit_region_path = options.path() ? options.path()->GetPath() : path_;
cc::PaintCanvas* c = DrawingCanvas();
......
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