DevTools: consistently use Maybe for optional values in the protocol generator.
BUG=580337
Review URL: https://codereview.chromium.org/1730383003
Cr-Original-Commit-Position: refs/heads/master@{#377505}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 794157c8a8848808c00194d820bf0a210550e914
diff --git a/CodeGenerator.py b/CodeGenerator.py
index e85a96d..5aa0820 100644
--- a/CodeGenerator.py
+++ b/CodeGenerator.py
@@ -108,12 +108,8 @@
"type": "OwnPtr<protocol::%s::%s>" % (domain_name, type["id"]),
"raw_type": "protocol::%s::%s" % (domain_name, type["id"]),
"create_type": "adoptPtr(new protocol::%s::%s())" % (domain_name, type["id"]),
- "optional_type": "OwnPtr<protocol::%s::%s>" % (domain_name, type["id"]),
- "optional_pass_type": "PassOwnPtr<protocol::%s::%s>" % (domain_name, type["id"]),
- "from_optional_out": "%s.release()",
"json_getter": "FromValue<protocol::%s::%s>::convert(getObject(%%s))" % (domain_name, type["id"]),
"json_type": "TypeObject",
- "nullable": True,
}
@@ -124,12 +120,8 @@
"to_pass_type": "%s.release()",
"type": "RefPtr<JSONObject>",
"raw_type": "RefPtr<JSONObject>",
- "optional_type": "RefPtr<JSONObject>",
- "optional_pass_type": "PassRefPtr<JSONObject>",
- "from_optional_out": "%s.release()",
"json_getter": "getObject(%s)",
"json_type": "TypeObject",
- "nullable": True,
}
@@ -140,11 +132,7 @@
"to_pass_type": "%s.release()",
"type": "RefPtr<JSONValue>",
"raw_type": "RefPtr<JSONValue>",
- "optional_type": "RefPtr<JSONValue>",
- "optional_pass_type": "PassRefPtr<JSONValue>",
- "from_optional_out": "%s.release()",
"json_getter": "getValue(%s)",
- "nullable": True,
}
@@ -156,12 +144,8 @@
"to_pass_type": "%s",
"type": "String",
"raw_type": "String",
- "optional_type": "protocol::OptionalValue<String>",
- "optional_pass_type": "const protocol::OptionalValue<String>&",
- "from_optional_out": "%s.get()",
"json_getter": "getString(%s)",
"json_type": "TypeString",
- "nullable": False,
}
typedefs = {
@@ -180,12 +164,8 @@
"to_pass_type": "%s",
"type": typedefs[type],
"raw_type": typedefs[type],
- "optional_type": "protocol::OptionalValue<" + typedefs[type] + ">",
- "optional_pass_type": "const protocol::OptionalValue<" + typedefs[type] + ">&",
- "from_optional_out": "%s.get()",
"json_getter": "get" + to_title_case(type) + "(%s)",
"json_type": jsontypes[type],
- "nullable": False,
}
type_definitions = {}
@@ -206,12 +186,8 @@
"raw_type": "protocol::Array<%s>" % type["raw_type"],
"create_type": "adoptPtr(new protocol::Array<%s>())" % type["raw_type"],
"out_type": "protocol::Array<%s>&" % type["raw_type"],
- "optional_type": "OwnPtr<protocol::Array<%s>>" % type["raw_type"],
- "optional_pass_type": "PassOwnPtr<protocol::Array<%s>>" % type["raw_type"],
- "from_optional_out": "%s.release()",
"json_getter": "protocol::Array<%s>::runtimeCast(getArray(%%s))" % type["raw_type"],
"json_type": "TypeArray",
- "nullable": True,
}
diff --git a/Dispatcher_cpp.template b/Dispatcher_cpp.template
index 95538cf..f25e871 100644
--- a/Dispatcher_cpp.template
+++ b/Dispatcher_cpp.template
@@ -13,7 +13,7 @@
namespace blink {
namespace protocol {
-using protocol::OptionalValue;
+using protocol::Maybe;
class DispatcherImpl : public Dispatcher {
public:
@@ -73,10 +73,10 @@
template<typename R, typename V, typename V0>
static R getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name);
- static OptionalValue<int> getInteger(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
- static OptionalValue<double> getNumber(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
- static OptionalValue<String> getString(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
- static OptionalValue<bool> getBoolean(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
+ static Maybe<int> getInteger(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
+ static Maybe<double> getNumber(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
+ static Maybe<String> getString(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
+ static Maybe<bool> getBoolean(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
static PassRefPtr<JSONObject> getObject(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
static PassRefPtr<JSONArray> getArray(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
@@ -108,7 +108,7 @@
void Dispatcher::{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback::sendSuccess(
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
- {{resolve_type(parameter).optional_pass_type}} {{parameter.name}}
+ const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}}
{%- else -%}
{{resolve_type(parameter).pass_type}} {{parameter.name}}
{%- endif -%}
@@ -118,9 +118,8 @@
RefPtr<JSONObject> resultObject = JSONObject::create();
{% for parameter in command.returns %}
{% if "optional" in parameter %}
- {{resolve_type(parameter).optional_type}} opt_{{parameter.name}} = {{parameter.name}};
- if (hasValue({{parameter.name}}))
- resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).from_optional_out % ("opt_" + parameter.name)}}));
+ if ({{parameter.name}}.isJust())
+ resultObject->setValue("{{parameter.name}}", toValue({{parameter.name}}));
{% else %}
resultObject->setValue("{{parameter.name}}", toValue({{parameter.name}}));
{% endif %}
@@ -144,7 +143,7 @@
RefPtr<JSONObject> paramsContainer = requestMessageObject->getObject("params");
JSONObject* paramsContainerPtr = paramsContainer.get();
{% for property in command.parameters %}
- {{resolve_type(property).optional_type}} in_{{property.name}} = {{resolve_type(property).json_getter % ("paramsContainerPtr, \"" + property.name + "\", " + ("true" if "optional" in property else "false") + ", protocolErrors")}};
+ Maybe<{{resolve_type(property).raw_type}}> in_{{property.name}} = {{resolve_type(property).json_getter % ("paramsContainerPtr, \"" + property.name + "\", " + ("true" if "optional" in property else "false") + ", protocolErrors")}};
{% endfor %}
{% endif %}
@@ -160,7 +159,7 @@
RefPtr<JSONObject> result = JSONObject::create();
{% for property in command.returns %}
{% if "optional" in property %}
- {{resolve_type(property).optional_type}} out_{{property.name}};
+ Maybe<{{resolve_type(property).raw_type}}> out_{{property.name}};
{% else %}
{{resolve_type(property).type}} out_{{property.name}};
{% endif %}
@@ -171,9 +170,9 @@
m_{{domain.domain | lower}}Agent->{{command.name}}(&error
{%- for property in command.parameters -%}
{%- if "optional" in property -%}
- , {{resolve_type(property).to_pass_type % ("in_" + property.name)}}
+ , in_{{property.name}}
{%- else -%}
- , {{resolve_type(property).from_optional_out % ("in_" + property.name)}}
+ , in_{{property.name}}.takeJust()
{%- endif -%}
{%- endfor %}
{%- if "async" in command -%}
@@ -187,8 +186,8 @@
if (!error.length()) {
{% for parameter in command.returns %}
{% if "optional" in parameter %}
- if (hasValue(out_{{parameter.name}}))
- result->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).from_optional_out % ("out_" + parameter.name)}}));
+ if (out_{{parameter.name}}.isJust())
+ result->setValue("{{parameter.name}}", toValue(out_{{parameter.name}}));
{% else %}
result->setValue("{{parameter.name}}", toValue(out_{{resolve_type(parameter).to_pass_type % parameter.name}}));
{% endif %}
@@ -316,32 +315,32 @@
static bool asArray(JSONValue* value, RefPtr<JSONArray>* output) { return value->asArray(output); }
};
-OptionalValue<int> DispatcherImpl::getInteger(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
+Maybe<int> DispatcherImpl::getInteger(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
{
bool valueFound = false;
int result = getPropertyValueImpl<int, int, int>(object, name, isOptional ? &valueFound : 0, protocolErrors, 0, AsMethodBridges::asInteger, "Number");
- return valueFound || !isOptional ? OptionalValue<int>(result) : OptionalValue<int>();
+ return valueFound || !isOptional ? Maybe<int>(result) : Maybe<int>();
}
-OptionalValue<double> DispatcherImpl::getNumber(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
+Maybe<double> DispatcherImpl::getNumber(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
{
bool valueFound = false;
double result = getPropertyValueImpl<double, double, double>(object, name, isOptional ? &valueFound : 0, protocolErrors, 0, AsMethodBridges::asNumber, "Number");
- return valueFound || !isOptional ? OptionalValue<double>(result) : OptionalValue<double>();
+ return valueFound || !isOptional ? Maybe<double>(result) : Maybe<double>();
}
-OptionalValue<String> DispatcherImpl::getString(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
+Maybe<String> DispatcherImpl::getString(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
{
bool valueFound = false;
String result = getPropertyValueImpl<String, String, String>(object, name, isOptional ? &valueFound : 0, protocolErrors, "", AsMethodBridges::asString, "String");
- return valueFound || !isOptional ? OptionalValue<String>(result) : OptionalValue<String>();
+ return valueFound || !isOptional ? Maybe<String>(result) : Maybe<String>();
}
-OptionalValue<bool> DispatcherImpl::getBoolean(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
+Maybe<bool> DispatcherImpl::getBoolean(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
{
bool valueFound = false;
bool result = getPropertyValueImpl<bool, bool, bool>(object, name, isOptional ? &valueFound : 0, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean");
- return valueFound || !isOptional ? OptionalValue<bool>(result) : OptionalValue<bool>();
+ return valueFound || !isOptional ? Maybe<bool>(result) : Maybe<bool>();
}
PassRefPtr<JSONObject> DispatcherImpl::getObject(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
diff --git a/Dispatcher_h.template b/Dispatcher_h.template
index e0cc255..6fd0b72 100644
--- a/Dispatcher_h.template
+++ b/Dispatcher_h.template
@@ -55,7 +55,7 @@
void sendSuccess(
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
- {{resolve_type(parameter).optional_pass_type}} {{parameter.name}}
+ const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}}
{%- else -%}
{{resolve_type(parameter).pass_type}} {{parameter.name}}
{%- endif -%}
@@ -67,7 +67,7 @@
virtual void {{command.name}}(ErrorString*
{%- for parameter in command.parameters -%}
{%- if "optional" in parameter -%}
- , {{resolve_type(parameter).optional_pass_type}} in_{{parameter.name}}
+ , const Maybe<{{resolve_type(parameter).raw_type}}>& in_{{parameter.name}}
{%- else -%}
, {{resolve_type(parameter).pass_type}} in_{{parameter.name}}
{%- endif -%}
@@ -77,7 +77,7 @@
{%- else -%}
{%- for parameter in command.returns -%}
{%- if "optional" in parameter -%}
- , {{resolve_type(parameter).optional_type}}* out_{{parameter.name}}
+ , Maybe<{{resolve_type(parameter).raw_type}}>* out_{{parameter.name}}
{%- else -%}
, {{resolve_type(parameter).type}}* out_{{parameter.name}}
{%- endif -%}
diff --git a/Frontend_cpp.template b/Frontend_cpp.template
index f68e040..c6d4bcb 100644
--- a/Frontend_cpp.template
+++ b/Frontend_cpp.template
@@ -26,7 +26,7 @@
void Frontend::{{domain.domain}}::{{event.name}}(
{%- for parameter in event.parameters %}
{% if "optional" in parameter -%}
- {{resolve_type(parameter).optional_pass_type}}
+ const Maybe<{{resolve_type(parameter).raw_type}}>&
{%- else -%}
{{resolve_type(parameter).pass_type}}
{%- endif %} {{parameter.name}}{%- if not loop.last -%}, {% endif -%}
@@ -37,9 +37,8 @@
RefPtr<JSONObject> paramsObject = JSONObject::create();
{% for parameter in event.parameters %}
{% if "optional" in parameter %}
- {{resolve_type(parameter).optional_type}} opt_{{parameter.name}} = {{parameter.name}};
- if (hasValue(opt_{{parameter.name}}))
- paramsObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).from_optional_out % ("opt_" + parameter.name)}}));
+ if ({{parameter.name}}.isJust())
+ paramsObject->setValue("{{parameter.name}}", toValue({{parameter.name}}));
{% else %}
paramsObject->setValue("{{parameter.name}}", toValue({{parameter.name}}));
{% endif %}
diff --git a/Frontend_h.template b/Frontend_h.template
index d0a630c..72a99a1 100644
--- a/Frontend_h.template
+++ b/Frontend_h.template
@@ -32,12 +32,7 @@
void {{event.name}}(
{%- for parameter in event.parameters -%}
{%- if "optional" in parameter -%}
- {{resolve_type(parameter).optional_pass_type}}
- {%- if resolve_type(parameter).nullable -%}
- {{parameter.name}} = nullptr
- {%- else -%}
- {{parameter.name}} = {{resolve_type(parameter).optional_type}}()
- {%- endif %}
+ const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}} = Maybe<{{resolve_type(parameter).raw_type}}>()
{%- else -%}
{{resolve_type(parameter).pass_type}} {{parameter.name}}
{%- endif -%}{%- if not loop.last -%}, {% endif -%}
diff --git a/TypeBuilder_cpp.template b/TypeBuilder_cpp.template
index 96db157..674e7a8 100644
--- a/TypeBuilder_cpp.template
+++ b/TypeBuilder_cpp.template
@@ -9,16 +9,10 @@
namespace blink {
namespace protocol {
-template<>
-PassRefPtr<JSONValue> toValue(const String& param)
-{
- return JSONString::create(param);
-}
-
-OptionalValue<String> optional(const String& value)
-{
- return value.isNull() ? OptionalValue<String>() : OptionalValue<String>(value);
-}
+PassRefPtr<JSONValue> toValue(int value) { return JSONBasicValue::create(value); }
+PassRefPtr<JSONValue> toValue(double value) { return JSONBasicValue::create(value); }
+PassRefPtr<JSONValue> toValue(bool value) { return JSONBasicValue::create(value); }
+PassRefPtr<JSONValue> toValue(const String& param) { return JSONString::create(param); }
// ------------- Enum values from types.
{% for domain in api.domains %}
diff --git a/TypeBuilder_h.template b/TypeBuilder_h.template
index 7374d9e..fc37c46 100644
--- a/TypeBuilder_h.template
+++ b/TypeBuilder_h.template
@@ -18,95 +18,94 @@
namespace protocol {
template<typename T>
-class OptionalValue {
+class Maybe {
public:
- OptionalValue() : m_hasValue(false) { }
- OptionalValue(const T& value) : m_hasValue(true), m_value(value) { }
-
- void operator=(T value)
- {
- m_value = value;
- m_hasValue = true;
- }
-
- T get() const
- {
- ASSERT(m_hasValue);
- return m_value;
- }
-
- T get(const T& defaultValue) const
- {
- return m_hasValue ? m_value : defaultValue;
- }
-
- bool hasValue() const
- {
- return m_hasValue;
- }
-
+ Maybe() { }
+ Maybe(PassOwnPtr<T> value) : m_value(value) { }
+ void operator=(PassOwnPtr<T> value) { m_value = value; }
+ T* fromJust() const { ASSERT(m_value); return m_value.get(); }
+ T* fromMaybe(PassOwnPtr<T> defaultValue) const { return m_value ? m_value.get() : defaultValue; }
+ bool isJust() const { return !!m_value; }
+ PassOwnPtr<T> takeJust() { ASSERT(m_value); return m_value.release(); }
private:
- bool m_hasValue;
- T m_value;
+ OwnPtr<T> m_value;
};
template<typename T>
-OptionalValue<T> optional(const T* value)
-{
- return value ? OptionalValue<T>(*value) : OptionalValue<T>();
-}
+class MaybeBase {
+public:
+ MaybeBase() : m_isJust(false) { }
+ MaybeBase(T value) : m_isJust(true), m_value(value) { }
+ void operator=(T value) { m_value = value; m_isJust = true; }
+ T fromJust() const { ASSERT(m_isJust); return m_value; }
+ T fromMaybe(const T& defaultValue) const { return m_isJust ? m_value : defaultValue; }
+ bool isJust() const { return m_isJust; }
+ T takeJust() { ASSERT(m_isJust); return m_value; }
-PLATFORM_EXPORT OptionalValue<String> optional(const String& value);
+protected:
+ bool m_isJust;
+ T m_value;
+};
+
+template<> class Maybe<bool> : public MaybeBase<bool> {
+public:
+ Maybe() { }
+ Maybe(bool value) : MaybeBase(value) { }
+ using MaybeBase::operator=;
+};
+
+template<> class Maybe<int> : public MaybeBase<int>
+{
+public:
+ Maybe() { }
+ Maybe(int value) : MaybeBase(value) { }
+ using MaybeBase::operator=;
+};
+
+template<> class Maybe<double> : public MaybeBase<double>
+{
+public:
+ Maybe() { }
+ Maybe(double value) : MaybeBase(value) { }
+ using MaybeBase::operator=;
+};
+
+template<> class Maybe<String> : public MaybeBase<String>
+{
+public:
+ Maybe() { }
+ Maybe(const String& value) : MaybeBase(value) { }
+ Maybe(const AtomicString& value) : MaybeBase(value) { }
+ using MaybeBase::operator=;
+};
template<typename T>
-OptionalValue<T> optional(const T& value)
-{
- return OptionalValue<T>(value);
-}
+class Maybe<RefPtr<T>> {
+public:
+ Maybe() { }
+ Maybe(RefPtr<T> value) : m_value(value) { }
+ Maybe(PassRefPtr<T> value) : m_value(value) { }
+ Maybe(T* value) : m_value(value) { }
+ void operator=(PassRefPtr<T> value) { m_value = value; }
+ PassRefPtr<T> fromJust() const { ASSERT(m_value); return m_value; }
+ PassRefPtr<T> fromMaybe(const PassRefPtr<T> defaultValue) const { return m_value || defaultValue; }
+ bool isJust() const { return !!m_value; }
+ PassRefPtr<T> takeJust() { return m_value; }
+
+protected:
+ RefPtr<T> m_value;
+};
template<typename T> class Array;
-template<typename T>
-bool hasValue(const protocol::OptionalValue<T>& t) { return t.hasValue(); }
-
-template<typename T>
-bool hasValue(T* value) { return !!value; }
-
-template<typename T>
-bool hasValue(const OwnPtr<T>& value) { return !!value; }
-
-template<typename T>
-bool hasValue(const PassOwnPtr<T>& value) { return !!value; }
-
-template<typename T>
-bool hasValue(const RefPtr<T>& value) { return !!value; }
-
-template<typename T>
-PassRefPtr<JSONValue> toValue(const T& param)
-{
- return JSONBasicValue::create(param);
-}
-
-template<>
+PLATFORM_EXPORT PassRefPtr<JSONValue> toValue(int value);
+PLATFORM_EXPORT PassRefPtr<JSONValue> toValue(double value);
+PLATFORM_EXPORT PassRefPtr<JSONValue> toValue(bool value);
PLATFORM_EXPORT PassRefPtr<JSONValue> toValue(const String& param);
-
-template<typename T>
-PassRefPtr<JSONValue> toValue(PassRefPtr<T> param)
-{
- return param;
-}
-
-template<typename T>
-PassRefPtr<JSONValue> toValue(const PassOwnPtr<protocol::Array<T>> param)
-{
- return param->asValue();
-}
-
-template<typename T>
-PassRefPtr<JSONValue> toValue(PassOwnPtr<T> param)
-{
- return param->asValue();
-}
+template<typename T> PassRefPtr<JSONValue> toValue(PassRefPtr<T> param) { return param; }
+template<typename T> PassRefPtr<JSONValue> toValue(T* param) { return param->asValue(); }
+template<typename T> PassRefPtr<JSONValue> toValue(PassOwnPtr<T> param) { return param->asValue(); }
+template<typename T> PassRefPtr<JSONValue> toValue(const Maybe<T>& param) { return toValue(param.fromJust()); }
template<typename T>
struct FromValue
@@ -360,6 +359,12 @@
RefPtr<JSONValue> value = m_object->get("{{property.name}}");
return value ? FromValue<{{resolve_type(property).raw_type}}>::convert(value) : defaultValue;
}
+
+ void set{{property.name | to_title_case}}(const Maybe<{{resolve_type(property).raw_type}}>& value)
+ {
+ if (value.isJust())
+ m_object->setValue("{{property.name}}", toValue(value.fromJust()));
+ }
{% else %}
{{resolve_type(property).return_type}} get{{property.name | to_title_case}}()
{
@@ -367,17 +372,12 @@
RefPtr<JSONValue> value = m_object->get("{{property.name}}");
return FromValue<{{resolve_type(property).raw_type}}>::convert(value);
}
- {% endif %}
void set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value)
{
- {% if property.optional and resolve_type(property).nullable %}
- if (value)
- m_object->setValue("{{property.name}}", toValue(value));
- {% else %}
m_object->setValue("{{property.name}}", toValue(value));
- {% endif %}
}
+ {% endif %}
{% endfor %}
PassRefPtr<JSONObject> asValue() { return m_object; }
@@ -404,12 +404,8 @@
{% for property in type.properties %}
{% if property.optional %}
- {{type.id}}Builder<STATE>& set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value)
+ {{type.id}}Builder<STATE>& set{{property.name | to_title_case}}(const Maybe<{{resolve_type(property).raw_type}}>& value)
{
- {% if resolve_type(property).nullable%}
- if (!value)
- return *this;
- {% endif %}
m_result->set{{property.name | to_title_case}}(value);
return *this;
}