Roll third_party/inspector_protocol to 73028acaa3646789fd2a3bfd0d79eb2d91b696b3

This roll includes:
  - Support config.protocol.options which defines which part of protocol definition should be generated. [1]
  - [inspector_protocol] Allow custom json parser. [2]
  - [inspector_protocol] Allow overriding specific config values. [3]
  - [inspector_protocol] Fix NoneType error when parsing config_values. [4]
  - [inspector_protocol] Support chromium code style. [5]
  - [inspector_protocol] Support features for content/ generator. [6]
  - [inspector_protocol] Fixed domain_json["has_exports"] flag for exported domains [7]

[1] https://codereview.chromium.org/2482993002
[2] https://codereview.chromium.org/2490733002
[3] https://codereview.chromium.org/2482093004
[4] https://codereview.chromium.org/2490823002
[5] https://codereview.chromium.org/2495353004
[6] https://codereview.chromium.org/2509573006
[7] https://codereview.chromium.org/2515343005

BUG=none
R=dgozman@chromium.org

Review-Url: https://codereview.chromium.org/2523743003
Cr-Commit-Position: refs/heads/master@{#41195}
This commit is contained in:
kozyatinskiy 2016-11-22 10:57:03 -08:00 committed by Commit bot
parent 292c4a0a2a
commit 211a6a8637
40 changed files with 387 additions and 209 deletions

View File

@ -140,7 +140,6 @@ v8_source_set("inspector") {
"inspected-context.h",
"java-script-call-frame.cc",
"java-script-call-frame.h",
"protocol-platform.h",
"remote-object-id.cc",
"remote-object-id.h",
"script-breakpoint.h",

View File

@ -44,8 +44,8 @@ int InjectedScriptNative::bind(v8::Local<v8::Value> value,
const String16& groupName) {
if (m_lastBoundObjectId <= 0) m_lastBoundObjectId = 1;
int id = m_lastBoundObjectId++;
m_idToWrappedObject[id] =
wrapUnique(new v8::Global<v8::Value>(m_isolate, value));
m_idToWrappedObject[id] = std::unique_ptr<v8::Global<v8::Value>>(
new v8::Global<v8::Value>(m_isolate, value));
addObjectToGroup(id, groupName);
return id;
}

View File

@ -105,9 +105,9 @@ std::unique_ptr<InjectedScript> InjectedScript::create(
if (inspector->getContext(contextGroupId, contextId) != inspectedContext)
return nullptr;
if (!injectedScriptValue->IsObject()) return nullptr;
return wrapUnique(new InjectedScript(inspectedContext,
injectedScriptValue.As<v8::Object>(),
std::move(injectedScriptNative)));
return std::unique_ptr<InjectedScript>(
new InjectedScript(inspectedContext, injectedScriptValue.As<v8::Object>(),
std::move(injectedScriptNative)));
}
InjectedScript::InjectedScript(
@ -158,7 +158,7 @@ Response InjectedScript::getProperties(
void InjectedScript::releaseObject(const String16& objectId) {
std::unique_ptr<protocol::Value> parsedObjectId =
protocol::parseJSON(objectId);
protocol::StringUtil::parseJSON(objectId);
if (!parsedObjectId) return;
protocol::DictionaryValue* object =
protocol::DictionaryValue::cast(parsedObjectId.get());

View File

@ -44,7 +44,6 @@
'inspector/inspected-context.h',
'inspector/java-script-call-frame.cc',
'inspector/java-script-call-frame.h',
'inspector/protocol-platform.h',
'inspector/remote-object-id.cc',
'inspector/remote-object-id.h',
'inspector/script-breakpoint.h',

View File

@ -3,7 +3,28 @@
"path": "js_protocol.json",
"package": "src/inspector/protocol",
"output": "protocol",
"namespace": ["v8_inspector", "protocol"]
"namespace": ["v8_inspector", "protocol"],
"options": [
{
"domain": "Schema"
},
{
"domain": "Runtime",
"async": ["evaluate", "awaitPromise", "callFunctionOn", "runScript"]
},
{
"domain": "Debugger"
},
{
"domain": "Console"
},
{
"domain": "Profiler"
},
{
"domain": "HeapProfiler"
}
]
},
"exported": {
@ -19,7 +40,6 @@
"lib": {
"package": "src/inspector/protocol",
"output": "protocol",
"string_header": "src/inspector/string-util.h",
"platform_header": "src/inspector/protocol-platform.h"
"string_header": "src/inspector/string-util.h"
}
}

View File

@ -31,10 +31,10 @@
#ifndef V8_INSPECTOR_JAVASCRIPTCALLFRAME_H_
#define V8_INSPECTOR_JAVASCRIPTCALLFRAME_H_
#include <memory>
#include <vector>
#include "src/base/macros.h"
#include "src/inspector/protocol-platform.h"
#include "include/v8.h"
@ -44,7 +44,8 @@ class JavaScriptCallFrame {
public:
static std::unique_ptr<JavaScriptCallFrame> create(
v8::Local<v8::Context> debuggerContext, v8::Local<v8::Object> callFrame) {
return wrapUnique(new JavaScriptCallFrame(debuggerContext, callFrame));
return std::unique_ptr<JavaScriptCallFrame>(
new JavaScriptCallFrame(debuggerContext, callFrame));
}
~JavaScriptCallFrame();

View File

@ -211,7 +211,6 @@
"commands": [
{
"name": "evaluate",
"async": true,
"parameters": [
{ "name": "expression", "type": "string", "description": "Expression to evaluate." },
{ "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." },
@ -231,7 +230,6 @@
},
{
"name": "awaitPromise",
"async": true,
"parameters": [
{ "name": "promiseObjectId", "$ref": "RemoteObjectId", "description": "Identifier of the promise." },
{ "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object that should be sent by value." },
@ -245,7 +243,6 @@
},
{
"name": "callFunctionOn",
"async": true,
"parameters": [
{ "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to call function on." },
{ "name": "functionDeclaration", "type": "string", "description": "Declaration of the function to call." },
@ -333,7 +330,6 @@
},
{
"name": "runScript",
"async": true,
"parameters": [
{ "name": "scriptId", "$ref": "ScriptId", "description": "Id of the script to run." },
{ "name": "executionContextId", "$ref": "ExecutionContextId", "optional": true, "description": "Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page." },

View File

@ -1,21 +0,0 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_INSPECTOR_PROTOCOLPLATFORM_H_
#define V8_INSPECTOR_PROTOCOLPLATFORM_H_
#include <memory>
#include "src/base/logging.h"
namespace v8_inspector {
template <typename T>
std::unique_ptr<T> wrapUnique(T* ptr) {
return std::unique_ptr<T>(ptr);
}
} // namespace v8_inspector
#endif // V8_INSPECTOR_PROTOCOLPLATFORM_H_

View File

@ -13,7 +13,8 @@ RemoteObjectIdBase::RemoteObjectIdBase() : m_injectedScriptId(0) {}
std::unique_ptr<protocol::DictionaryValue>
RemoteObjectIdBase::parseInjectedScriptId(const String16& objectId) {
std::unique_ptr<protocol::Value> parsedValue = protocol::parseJSON(objectId);
std::unique_ptr<protocol::Value> parsedValue =
protocol::StringUtil::parseJSON(objectId);
if (!parsedValue || parsedValue->type() != protocol::Value::TypeObject)
return nullptr;

View File

@ -132,7 +132,8 @@ std::unique_ptr<V8Regex> createSearchRegex(V8InspectorImpl* inspector,
const String16& query,
bool caseSensitive, bool isRegex) {
String16 regexSource = isRegex ? query : createSearchRegexSource(query);
return wrapUnique(new V8Regex(inspector, regexSource, caseSensitive));
return std::unique_ptr<V8Regex>(
new V8Regex(inspector, regexSource, caseSensitive));
}
} // namespace

View File

@ -15,7 +15,6 @@
#include <string>
#include "src/base/platform/platform.h"
#include "src/inspector/protocol-platform.h"
namespace v8_inspector {

View File

@ -93,19 +93,20 @@ bool stringViewStartsWith(const StringView& string, const char* prefix) {
namespace protocol {
std::unique_ptr<protocol::Value> parseJSON(const StringView& string) {
std::unique_ptr<protocol::Value> StringUtil::parseJSON(
const StringView& string) {
if (!string.length()) return nullptr;
if (string.is8Bit()) {
return protocol::parseJSON(string.characters8(),
return parseJSONCharacters(string.characters8(),
static_cast<int>(string.length()));
}
return protocol::parseJSON(string.characters16(),
return parseJSONCharacters(string.characters16(),
static_cast<int>(string.length()));
}
std::unique_ptr<protocol::Value> parseJSON(const String16& string) {
std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String16& string) {
if (!string.length()) return nullptr;
return protocol::parseJSON(string.characters16(),
return parseJSONCharacters(string.characters16(),
static_cast<int>(string.length()));
}
@ -119,7 +120,7 @@ std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) {
// static
std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string) {
return wrapUnique(new StringBufferImpl(string));
return std::unique_ptr<StringBufferImpl>(new StringBufferImpl(string));
}
StringBufferImpl::StringBufferImpl(String16& string) {

View File

@ -5,6 +5,9 @@
#ifndef V8_INSPECTOR_STRINGUTIL_H_
#define V8_INSPECTOR_STRINGUTIL_H_
#include <memory>
#include "src/base/logging.h"
#include "src/base/macros.h"
#include "src/inspector/string-16.h"
@ -33,11 +36,10 @@ class StringUtil {
static void builderReserve(StringBuilder& builder, size_t capacity) {
builder.reserveCapacity(capacity);
}
static std::unique_ptr<protocol::Value> parseJSON(const String16& json);
static std::unique_ptr<protocol::Value> parseJSON(const StringView& json);
};
std::unique_ptr<protocol::Value> parseJSON(const StringView& json);
std::unique_ptr<protocol::Value> parseJSON(const String16& json);
} // namespace protocol
v8::Local<v8::String> toV8String(v8::Isolate*, const String16&);

View File

@ -361,7 +361,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
V8InspectorImpl* inspector = inspectedContext->inspector();
v8::Local<v8::Context> context = inspectedContext->context();
std::unique_ptr<V8ConsoleMessage> message = wrapUnique(
std::unique_ptr<V8ConsoleMessage> message(
new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16()));
if (stackTrace && !stackTrace->isEmpty()) {
message->m_url = toString16(stackTrace->topSourceURL());
@ -372,8 +372,8 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
message->m_type = type;
message->m_contextId = contextId;
for (size_t i = 0; i < arguments.size(); ++i)
message->m_arguments.push_back(
wrapUnique(new v8::Global<v8::Value>(isolate, arguments.at(i))));
message->m_arguments.push_back(std::unique_ptr<v8::Global<v8::Value>>(
new v8::Global<v8::Value>(isolate, arguments.at(i))));
if (arguments.size())
message->m_message = V8ValueStringBuilder::toString(arguments[0], context);
@ -404,7 +404,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForException(
std::unique_ptr<V8StackTraceImpl> stackTrace, int scriptId,
v8::Isolate* isolate, const String16& message, int contextId,
v8::Local<v8::Value> exception, unsigned exceptionId) {
std::unique_ptr<V8ConsoleMessage> consoleMessage = wrapUnique(
std::unique_ptr<V8ConsoleMessage> consoleMessage(
new V8ConsoleMessage(V8MessageOrigin::kException, timestamp, message));
consoleMessage->setLocation(url, lineNumber, columnNumber,
std::move(stackTrace), scriptId);
@ -413,7 +413,8 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForException(
if (contextId && !exception.IsEmpty()) {
consoleMessage->m_contextId = contextId;
consoleMessage->m_arguments.push_back(
wrapUnique(new v8::Global<v8::Value>(isolate, exception)));
std::unique_ptr<v8::Global<v8::Value>>(
new v8::Global<v8::Value>(isolate, exception)));
}
return consoleMessage;
}
@ -422,7 +423,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForException(
std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForRevokedException(
double timestamp, const String16& messageText,
unsigned revokedExceptionId) {
std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage(
std::unique_ptr<V8ConsoleMessage> message(new V8ConsoleMessage(
V8MessageOrigin::kRevokedException, timestamp, messageText));
message->m_revokedExceptionId = revokedExceptionId;
return message;

View File

@ -1056,7 +1056,7 @@ void V8DebuggerAgentImpl::didParseSource(
std::unique_ptr<protocol::DictionaryValue> executionContextAuxData;
if (!script->executionContextAuxData().isEmpty())
executionContextAuxData = protocol::DictionaryValue::cast(
protocol::parseJSON(script->executionContextAuxData()));
protocol::StringUtil::parseJSON(script->executionContextAuxData()));
bool isLiveEdit = script->isLiveEdit();
bool hasSourceURL = script->hasSourceURL();
String16 scriptId = script->scriptId();

View File

@ -4,7 +4,6 @@
#include "src/inspector/v8-debugger-script.h"
#include "src/inspector/protocol-platform.h"
#include "src/inspector/string-util.h"
namespace v8_inspector {

View File

@ -130,8 +130,8 @@ void V8Debugger::getCompiledScripts(
if (!script->ContextData().ToLocal(&v8ContextData)) continue;
String16 contextData = toProtocolString(v8ContextData);
if (contextData.find(contextPrefix) != 0) continue;
result.push_back(
wrapUnique(new V8DebuggerScript(m_isolate, script, false)));
result.push_back(std::unique_ptr<V8DebuggerScript>(
new V8DebuggerScript(m_isolate, script, false)));
}
}
@ -354,7 +354,7 @@ Response V8Debugger::setScriptSource(
std::unique_ptr<v8::Context::Scope> contextScope;
if (!isPaused())
contextScope = wrapUnique(new v8::Context::Scope(debuggerContext()));
contextScope.reset(new v8::Context::Scope(debuggerContext()));
v8::Local<v8::Value> argv[] = {toV8String(m_isolate, sourceID), newSource,
v8Boolean(dryRun, m_isolate)};
@ -596,7 +596,8 @@ void V8Debugger::handleV8DebugEvent(
m_wasmTranslation.AddScript(scriptWrapper.As<v8::Object>());
} else if (m_ignoreScriptParsedEventsCounter == 0) {
agent->didParseSource(
wrapUnique(new V8DebuggerScript(m_isolate, script, inLiveEditScope)),
std::unique_ptr<V8DebuggerScript>(
new V8DebuggerScript(m_isolate, script, inLiveEditScope)),
event == v8::AfterCompile);
}
} else if (event == v8::Exception) {

View File

@ -216,7 +216,7 @@ Response V8HeapProfilerAgentImpl::takeHeapSnapshot(Maybe<bool> reportProgress) {
if (!profiler) return Response::Error("Cannot access v8 heap profiler");
std::unique_ptr<HeapSnapshotProgress> progress;
if (reportProgress.fromMaybe(false))
progress = wrapUnique(new HeapSnapshotProgress(&m_frontend));
progress.reset(new HeapSnapshotProgress(&m_frontend));
GlobalObjectNameResolver resolver(m_session);
const v8::HeapSnapshot* snapshot =
@ -260,7 +260,8 @@ Response V8HeapProfilerAgentImpl::addInspectedHeapObject(
if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject))
return Response::Error("Object is not available");
m_session->addInspectedObject(wrapUnique(new InspectableHeapObject(id)));
m_session->addInspectedObject(
std::unique_ptr<InspectableHeapObject>(new InspectableHeapObject(id)));
return Response::OK();
}

View File

@ -45,7 +45,7 @@ namespace v8_inspector {
std::unique_ptr<V8Inspector> V8Inspector::create(v8::Isolate* isolate,
V8InspectorClient* client) {
return wrapUnique(new V8InspectorImpl(isolate, client));
return std::unique_ptr<V8Inspector>(new V8InspectorImpl(isolate, client));
}
V8InspectorImpl::V8InspectorImpl(v8::Isolate* isolate,
@ -163,12 +163,12 @@ V8ConsoleMessageStorage* V8InspectorImpl::ensureConsoleMessageStorage(
ConsoleStorageMap::iterator storageIt =
m_consoleStorageMap.find(contextGroupId);
if (storageIt == m_consoleStorageMap.end())
storageIt =
m_consoleStorageMap
.insert(std::make_pair(
contextGroupId,
wrapUnique(new V8ConsoleMessageStorage(this, contextGroupId))))
.first;
storageIt = m_consoleStorageMap
.insert(std::make_pair(
contextGroupId,
std::unique_ptr<V8ConsoleMessageStorage>(
new V8ConsoleMessageStorage(this, contextGroupId))))
.first;
return storageIt->second.get();
}
@ -217,15 +217,16 @@ void V8InspectorImpl::contextCreated(const V8ContextInfo& info) {
ContextsByGroupMap::iterator contextIt = m_contexts.find(info.contextGroupId);
if (contextIt == m_contexts.end())
contextIt = m_contexts
.insert(std::make_pair(info.contextGroupId,
wrapUnique(new ContextByIdMap())))
.insert(std::make_pair(
info.contextGroupId,
std::unique_ptr<ContextByIdMap>(new ContextByIdMap())))
.first;
const auto& contextById = contextIt->second;
DCHECK(contextById->find(contextId) == contextById->cend());
InspectedContext* context = new InspectedContext(this, info, contextId);
(*contextById)[contextId] = wrapUnique(context);
(*contextById)[contextId].reset(context);
SessionMap::iterator sessionIt = m_sessions.find(info.contextGroupId);
if (sessionIt != m_sessions.end())
sessionIt->second->runtimeAgent()->reportExecutionContextCreated(context);
@ -291,8 +292,8 @@ unsigned V8InspectorImpl::exceptionThrown(
std::unique_ptr<V8StackTrace> stackTrace, int scriptId) {
int contextGroupId = V8Debugger::getGroupId(context);
if (!contextGroupId || m_muteExceptionsMap[contextGroupId]) return 0;
std::unique_ptr<V8StackTraceImpl> stackTraceImpl =
wrapUnique(static_cast<V8StackTraceImpl*>(stackTrace.release()));
std::unique_ptr<V8StackTraceImpl> stackTraceImpl(
static_cast<V8StackTraceImpl*>(stackTrace.release()));
unsigned exceptionId = nextExceptionId();
std::unique_ptr<V8ConsoleMessage> consoleMessage =
V8ConsoleMessage::createForException(

View File

@ -40,7 +40,7 @@ bool V8InspectorSession::canDispatchMethod(const StringView& method) {
std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(
V8InspectorImpl* inspector, int contextGroupId,
V8Inspector::Channel* channel, const StringView& state) {
return wrapUnique(
return std::unique_ptr<V8InspectorSessionImpl>(
new V8InspectorSessionImpl(inspector, contextGroupId, channel, state));
}
@ -62,35 +62,35 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector,
m_schemaAgent(nullptr) {
if (savedState.length()) {
std::unique_ptr<protocol::Value> state =
protocol::parseJSON(toString16(savedState));
protocol::StringUtil::parseJSON(toString16(savedState));
if (state) m_state = protocol::DictionaryValue::cast(std::move(state));
if (!m_state) m_state = protocol::DictionaryValue::create();
} else {
m_state = protocol::DictionaryValue::create();
}
m_runtimeAgent = wrapUnique(new V8RuntimeAgentImpl(
m_runtimeAgent.reset(new V8RuntimeAgentImpl(
this, this, agentState(protocol::Runtime::Metainfo::domainName)));
protocol::Runtime::Dispatcher::wire(&m_dispatcher, m_runtimeAgent.get());
m_debuggerAgent = wrapUnique(new V8DebuggerAgentImpl(
m_debuggerAgent.reset(new V8DebuggerAgentImpl(
this, this, agentState(protocol::Debugger::Metainfo::domainName)));
protocol::Debugger::Dispatcher::wire(&m_dispatcher, m_debuggerAgent.get());
m_profilerAgent = wrapUnique(new V8ProfilerAgentImpl(
m_profilerAgent.reset(new V8ProfilerAgentImpl(
this, this, agentState(protocol::Profiler::Metainfo::domainName)));
protocol::Profiler::Dispatcher::wire(&m_dispatcher, m_profilerAgent.get());
m_heapProfilerAgent = wrapUnique(new V8HeapProfilerAgentImpl(
m_heapProfilerAgent.reset(new V8HeapProfilerAgentImpl(
this, this, agentState(protocol::HeapProfiler::Metainfo::domainName)));
protocol::HeapProfiler::Dispatcher::wire(&m_dispatcher,
m_heapProfilerAgent.get());
m_consoleAgent = wrapUnique(new V8ConsoleAgentImpl(
m_consoleAgent.reset(new V8ConsoleAgentImpl(
this, this, agentState(protocol::Console::Metainfo::domainName)));
protocol::Console::Dispatcher::wire(&m_dispatcher, m_consoleAgent.get());
m_schemaAgent = wrapUnique(new V8SchemaAgentImpl(
m_schemaAgent.reset(new V8SchemaAgentImpl(
this, this, agentState(protocol::Schema::Metainfo::domainName)));
protocol::Schema::Dispatcher::wire(&m_dispatcher, m_schemaAgent.get());
@ -305,7 +305,7 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
void V8InspectorSessionImpl::dispatchProtocolMessage(
const StringView& message) {
m_dispatcher.dispatch(protocol::parseJSON(message));
m_dispatcher.dispatch(protocol::StringUtil::parseJSON(message));
}
std::unique_ptr<StringBuffer> V8InspectorSessionImpl::stateJSON() {
@ -366,7 +366,8 @@ void V8InspectorSessionImpl::schedulePauseOnNextStatement(
const StringView& breakReason, const StringView& breakDetails) {
m_debuggerAgent->schedulePauseOnNextStatement(
toString16(breakReason),
protocol::DictionaryValue::cast(protocol::parseJSON(breakDetails)));
protocol::DictionaryValue::cast(
protocol::StringUtil::parseJSON(breakDetails)));
}
void V8InspectorSessionImpl::cancelPauseOnNextStatement() {
@ -377,7 +378,8 @@ void V8InspectorSessionImpl::breakProgram(const StringView& breakReason,
const StringView& breakDetails) {
m_debuggerAgent->breakProgram(
toString16(breakReason),
protocol::DictionaryValue::cast(protocol::parseJSON(breakDetails)));
protocol::DictionaryValue::cast(
protocol::StringUtil::parseJSON(breakDetails)));
}
void V8InspectorSessionImpl::setSkipAllPauses(bool skip) {

View File

@ -4,7 +4,6 @@
#include "src/inspector/v8-internal-value-type.h"
#include "src/inspector/protocol-platform.h"
#include "src/inspector/string-util.h"
namespace v8_inspector {

View File

@ -706,7 +706,7 @@ void V8RuntimeAgentImpl::reportExecutionContextCreated(
.build();
if (!context->auxData().isEmpty())
description->setAuxData(protocol::DictionaryValue::cast(
protocol::parseJSON(context->auxData())));
protocol::StringUtil::parseJSON(context->auxData())));
m_frontend.executionContextCreated(std::move(description));
}

View File

@ -180,7 +180,7 @@ std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture(
std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() {
std::vector<Frame> framesCopy(m_frames);
return wrapUnique(
return std::unique_ptr<V8StackTraceImpl>(
new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy,
m_parent ? m_parent->cloneImpl() : nullptr));
}
@ -189,7 +189,7 @@ std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() {
std::vector<Frame> frames;
for (size_t i = 0; i < m_frames.size(); i++)
frames.push_back(m_frames.at(i).clone());
return wrapUnique(
return std::unique_ptr<V8StackTraceImpl>(
new V8StackTraceImpl(m_contextGroupId, m_description, frames, nullptr));
}

View File

@ -7,6 +7,7 @@ import sys
import optparse
import collections
import functools
import re
try:
import json
except ImportError:
@ -52,6 +53,7 @@ def read_config():
cmdline_parser.add_option("--output_base")
cmdline_parser.add_option("--jinja_dir")
cmdline_parser.add_option("--config")
cmdline_parser.add_option("--config_value", action="append", type="string")
arg_options, _ = cmdline_parser.parse_args()
jinja_dir = arg_options.jinja_dir
if not jinja_dir:
@ -63,6 +65,9 @@ def read_config():
if not config_file:
raise Exception("Config file name must be specified")
config_base = os.path.dirname(config_file)
config_values = arg_options.config_value
if not config_values:
config_values = []
except Exception:
# Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
exc = sys.exc_info()[1]
@ -75,6 +80,8 @@ def read_config():
config_partial = json_to_object(config_json_string, output_base, config_base)
config_json_file.close()
defaults = {
".use_snake_file_names": False,
".use_title_case_methods": False,
".imported": False,
".imported.export_macro": "",
".imported.export_header": False,
@ -82,6 +89,7 @@ def read_config():
".imported.package": False,
".protocol.export_macro": "",
".protocol.export_header": False,
".protocol.options": False,
".exported": False,
".exported.export_macro": "",
".exported.export_header": False,
@ -89,6 +97,10 @@ def read_config():
".lib.export_macro": "",
".lib.export_header": False,
}
for key_value in config_values:
parts = key_value.split("=")
if len(parts) == 2:
defaults["." + parts[0]] = parts[1]
return (jinja_dir, config_file, init_defaults(config_partial, "", defaults))
except Exception:
# Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
@ -109,7 +121,17 @@ def dash_to_camelcase(word):
return prefix + "".join(to_title_case(x) or "-" for x in word.split("-"))
def initialize_jinja_env(jinja_dir, cache_dir):
def to_snake_case(name):
return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name, sys.maxint).lower()
def to_method_case(config, name):
if config.use_title_case_methods:
return to_title_case(name)
return name
def initialize_jinja_env(jinja_dir, cache_dir, config):
# pylint: disable=F0401
sys.path.insert(1, os.path.abspath(jinja_dir))
import jinja2
@ -122,7 +144,7 @@ def initialize_jinja_env(jinja_dir, cache_dir):
keep_trailing_newline=True, # newline-terminate generated files
lstrip_blocks=True, # so can indent control flow tags
trim_blocks=True)
jinja_env.filters.update({"to_title_case": to_title_case, "dash_to_camelcase": dash_to_camelcase})
jinja_env.filters.update({"to_title_case": to_title_case, "dash_to_camelcase": dash_to_camelcase, "to_method_case": functools.partial(to_method_case, config)})
jinja_env.add_extension("jinja2.ext.loopcontrols")
return jinja_env
@ -149,23 +171,39 @@ def patch_full_qualified_refs(protocol):
patch_full_qualified_refs_in_domain(domain, domain["domain"])
def calculate_exports(protocol):
def calculate_exports_in_json(json_value):
has_exports = False
def calculate_imports_and_exports(config, protocol):
def has_exports(json_value, clear):
result = False
if isinstance(json_value, list):
for item in json_value:
has_exports = calculate_exports_in_json(item) or has_exports
result = has_exports(item, clear) or result
if isinstance(json_value, dict):
has_exports = ("exported" in json_value and json_value["exported"]) or has_exports
if "exported" in json_value and json_value["exported"]:
result = True
if "exported" in json_value and clear:
del json_value["exported"]
for key in json_value:
has_exports = calculate_exports_in_json(json_value[key]) or has_exports
return has_exports
result = has_exports(json_value[key], clear) or result
return result
protocol.json_api["has_exports"] = False
imported_domains = protocol.imported_domains
if config.protocol.options:
protocol.generate_domains = [rule.domain for rule in config.protocol.options]
imported_domains = list(set(protocol.imported_domains) - set(protocol.generate_domains))
exported_domains = protocol.generate_domains
protocol.imported_domains = []
protocol.exported_domains = []
for domain_json in protocol.json_api["domains"]:
domain_json["has_exports"] = calculate_exports_in_json(domain_json)
if domain_json["has_exports"] and domain_json["domain"] in protocol.generate_domains:
protocol.json_api["has_exports"] = True
domain = domain_json["domain"]
clear = domain not in exported_domains and domain not in imported_domains
if not has_exports(domain_json, clear):
continue
if domain in exported_domains:
domain_json["has_exports"] = True
protocol.exported_domains.append(domain)
if domain in imported_domains:
protocol.imported_domains.append(domain)
def create_imported_type_definition(domain_name, type, imported_namespace):
@ -286,7 +324,6 @@ def wrap_array_definition(type):
"raw_type": "protocol::Array<%s>" % type["raw_type"],
"raw_pass_type": "protocol::Array<%s>*" % type["raw_type"],
"raw_return_type": "protocol::Array<%s>*" % type["raw_type"],
"create_type": "wrapUnique(new protocol::Array<%s>())" % type["raw_type"],
"out_type": "protocol::Array<%s>&" % type["raw_type"],
}
@ -337,15 +374,68 @@ def join_arrays(dict, keys):
return result
def has_disable(commands):
for command in commands:
if command["name"] == "disable" and (not ("handlers" in command) or "renderer" in command["handlers"]):
return True
def generate_command(protocol, config, domain, command):
if not config.protocol.options:
return domain in protocol.generate_domains
for rule in config.protocol.options:
if rule.domain != domain:
continue
if hasattr(rule, "include"):
return command in rule.include
if hasattr(rule, "exclude"):
return command not in rule.exclude
return True
return False
def format_include(header):
return "\"" + header + "\"" if header[0] not in "<\"" else header
def generate_event(protocol, config, domain, event):
if not config.protocol.options:
return domain in protocol.generate_domains
for rule in config.protocol.options:
if rule.domain != domain:
continue
if hasattr(rule, "include_events"):
return event in rule.include_events
if hasattr(rule, "exclude_events"):
return event not in rule.exclude_events
return True
return False
def is_async_command(protocol, config, domain, command):
if not config.protocol.options:
return False
for rule in config.protocol.options:
if rule.domain != domain:
continue
if hasattr(rule, "async"):
return command in rule.async
return False
return False
def generate_disable(protocol, config, domain):
if "commands" not in domain:
return True
for command in domain["commands"]:
if command["name"] == "disable" and generate_command(protocol, config, domain["domain"], "disable"):
return False
return True
def format_include(config, header, file_name=None):
if file_name is not None:
header = header + "/" + file_name + ".h"
header = "\"" + header + "\"" if header[0] not in "<\"" else header
if config.use_snake_file_names:
header = to_snake_case(header)
return header
def to_file_name(config, file_name):
if config.use_snake_file_names:
return to_snake_case(file_name).replace(".cpp", ".cc")
return file_name
def read_protocol_file(file_name, json_api):
@ -367,6 +457,7 @@ class Protocol(object):
self.json_api = {}
self.generate_domains = []
self.imported_domains = []
self.exported_domains = []
def main():
@ -377,20 +468,18 @@ def main():
protocol.generate_domains = read_protocol_file(config.protocol.path, protocol.json_api)
protocol.imported_domains = read_protocol_file(config.imported.path, protocol.json_api) if config.imported else []
patch_full_qualified_refs(protocol)
calculate_exports(protocol)
calculate_imports_and_exports(config, protocol)
create_type_definitions(protocol, "::".join(config.imported.namespace) if config.imported else "")
if not config.exported:
for domain_json in protocol.json_api["domains"]:
if domain_json["has_exports"] and domain_json["domain"] in protocol.generate_domains:
sys.stderr.write("Domain %s is exported, but config is missing export entry\n\n" % domain_json["domain"])
exit(1)
if not config.exported and len(protocol.exported_domains):
sys.stderr.write("Domains [%s] are exported, but config is missing export entry\n\n" % ", ".join(protocol.exported_domains))
exit(1)
if not os.path.exists(config.protocol.output):
os.mkdir(config.protocol.output)
if protocol.json_api["has_exports"] and not os.path.exists(config.exported.output):
if len(protocol.exported_domains) and not os.path.exists(config.exported.output):
os.mkdir(config.exported.output)
jinja_env = initialize_jinja_env(jinja_dir, config.protocol.output)
jinja_env = initialize_jinja_env(jinja_dir, config.protocol.output, config)
inputs = []
inputs.append(__file__)
@ -419,22 +508,25 @@ def main():
"join_arrays": join_arrays,
"resolve_type": functools.partial(resolve_type, protocol),
"type_definition": functools.partial(type_definition, protocol),
"has_disable": has_disable,
"format_include": format_include
"generate_command": functools.partial(generate_command, protocol, config),
"generate_event": functools.partial(generate_event, protocol, config),
"is_async_command": functools.partial(is_async_command, protocol, config),
"generate_disable": functools.partial(generate_disable, protocol, config),
"format_include": functools.partial(format_include, config),
}
if domain["domain"] in protocol.generate_domains:
outputs[os.path.join(config.protocol.output, class_name + ".h")] = h_template.render(template_context)
outputs[os.path.join(config.protocol.output, class_name + ".cpp")] = cpp_template.render(template_context)
if domain["has_exports"]:
outputs[os.path.join(config.exported.output, class_name + ".h")] = exported_template.render(template_context)
if domain["domain"] in protocol.imported_domains and domain["has_exports"]:
outputs[os.path.join(config.protocol.output, class_name + ".h")] = imported_template.render(template_context)
outputs[os.path.join(config.protocol.output, to_file_name(config, class_name + ".h"))] = h_template.render(template_context)
outputs[os.path.join(config.protocol.output, to_file_name(config, class_name + ".cpp"))] = cpp_template.render(template_context)
if domain["domain"] in protocol.exported_domains:
outputs[os.path.join(config.exported.output, to_file_name(config, class_name + ".h"))] = exported_template.render(template_context)
if domain["domain"] in protocol.imported_domains:
outputs[os.path.join(config.protocol.output, to_file_name(config, class_name + ".h"))] = imported_template.render(template_context)
if config.lib:
template_context = {
"config": config,
"format_include": format_include,
"format_include": functools.partial(format_include, config),
}
lib_templates_dir = os.path.join(module_path, "lib")
@ -475,9 +567,9 @@ def main():
parts.append(template.render(template_context))
outputs[file_name] = "\n\n".join(parts)
generate_lib_file(os.path.join(config.lib.output, "Forward.h"), forward_h_templates)
generate_lib_file(os.path.join(config.lib.output, "Protocol.h"), lib_h_templates)
generate_lib_file(os.path.join(config.lib.output, "Protocol.cpp"), lib_cpp_templates)
generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Forward.h")), forward_h_templates)
generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.h")), lib_h_templates)
generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.cpp")), lib_cpp_templates)
# Make gyp / make generatos happy, otherwise make rebuilds world.
inputs_ts = max(map(os.path.getmtime, inputs))

View File

@ -2,7 +2,7 @@ Name: inspector protocol
Short Name: inspector_protocol
URL: https://chromium.googlesource.com/deps/inspector_protocol/
Version: 0
Revision: ebda02bf94a742a2e26e4f818df1fc77517ac44c
Revision: ef8aa4e19e53a105843cd469e8122d098d902b47
License: BSD
License File: LICENSE
Security Critical: no

View File

@ -67,6 +67,15 @@ template("inspector_protocol_generate") {
rebase_path(invoker.config_file, root_build_dir),
]
if (defined(invoker.config_values)) {
foreach(value, invoker.config_values) {
args += [
"--config_value",
value,
]
}
}
outputs = get_path_info(rebase_path(invoker.outputs, ".", invoker.out_dir),
"abspath")

View File

@ -19,7 +19,7 @@ class Array {
public:
static std::unique_ptr<Array<T>> create()
{
return wrapUnique(new Array<T>());
return std::unique_ptr<Array<T>>(new Array<T>());
}
static std::unique_ptr<Array<T>> parse(protocol::Value* value, ErrorSupport* errors)
@ -74,7 +74,7 @@ class ArrayBase {
public:
static std::unique_ptr<Array<T>> create()
{
return wrapUnique(new Array<T>());
return std::unique_ptr<Array<T>>(new Array<T>());
}
static std::unique_ptr<Array<T>> parse(protocol::Value* value, ErrorSupport* errors)

View File

@ -5,7 +5,7 @@
#ifndef {{"_".join(config.protocol.namespace)}}_Collections_h
#define {{"_".join(config.protocol.namespace)}}_Collections_h
#include "{{config.protocol.package}}/Forward.h"
#include {{format_include(config.protocol.package, "Forward")}}
#include <cstddef>
#if defined(__APPLE__) && !defined(_LIBCPP_VERSION)

View File

@ -38,6 +38,16 @@ DispatchResponse DispatchResponse::InternalError()
return result;
}
// static
DispatchResponse DispatchResponse::InvalidParams(const String& error)
{
DispatchResponse result;
result.m_status = kError;
result.m_errorCode = kInvalidParams;
result.m_errorMessage = error;
return result;
}
// static
DispatchResponse DispatchResponse::FallThrough()
{
@ -58,9 +68,10 @@ DispatcherBase::WeakPtr::~WeakPtr()
m_dispatcher->m_weakPtrs.erase(this);
}
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId)
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId)
: m_backendImpl(std::move(backendImpl))
, m_callId(callId) { }
, m_callId(callId)
, m_callbackId(callbackId) { }
DispatcherBase::Callback::~Callback() = default;
@ -77,18 +88,40 @@ void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::Dictionary
m_backendImpl = nullptr;
}
void DispatcherBase::Callback::fallThroughIfActive()
{
if (!m_backendImpl || !m_backendImpl->get())
return;
m_backendImpl->get()->markFallThrough(m_callbackId);
m_backendImpl = nullptr;
}
DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
: m_frontendChannel(frontendChannel) { }
: m_frontendChannel(frontendChannel)
, m_lastCallbackId(0)
, m_lastCallbackFallThrough(false) { }
DispatcherBase::~DispatcherBase()
{
clearFrontend();
}
int DispatcherBase::nextCallbackId()
{
m_lastCallbackFallThrough = false;
return ++m_lastCallbackId;
}
void DispatcherBase::markFallThrough(int callbackId)
{
DCHECK(callbackId == m_lastCallbackId);
m_lastCallbackFallThrough = true;
}
// static
bool DispatcherBase::getCommandName(const String& message, String* result)
{
std::unique_ptr<protocol::Value> value = parseJSON(message);
std::unique_ptr<protocol::Value> value = StringUtil::parseJSON(message);
if (!value)
return false;
@ -169,7 +202,13 @@ std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
}
UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
: m_frontendChannel(frontendChannel) { }
: m_frontendChannel(frontendChannel)
, m_fallThroughForNotFound(false) { }
void UberDispatcher::setFallThroughForNotFound(bool fallThroughForNotFound)
{
m_fallThroughForNotFound = fallThroughForNotFound;
}
void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
{
@ -206,12 +245,16 @@ DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedM
size_t dotIndex = method.find(".");
if (dotIndex == StringUtil::kNotFound) {
if (m_fallThroughForNotFound)
return DispatchResponse::kFallThrough;
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return DispatchResponse::kError;
}
String domain = StringUtil::substring(method, 0, dotIndex);
auto it = m_dispatchers.find(domain);
if (it == m_dispatchers.end()) {
if (m_fallThroughForNotFound)
return DispatchResponse::kFallThrough;
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return DispatchResponse::kError;
}

View File

@ -42,6 +42,7 @@ public:
static DispatchResponse OK();
static DispatchResponse Error(const String&);
static DispatchResponse InternalError();
static DispatchResponse InvalidParams(const String&);
static DispatchResponse FallThrough();
private:
@ -67,16 +68,18 @@ public:
class {{config.lib.export_macro}} Callback {
public:
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId);
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, int callbackId);
virtual ~Callback();
void dispose();
protected:
void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const DispatchResponse& response);
void fallThroughIfActive();
private:
std::unique_ptr<WeakPtr> m_backendImpl;
int m_callId;
int m_callbackId;
};
explicit DispatcherBase(FrontendChannel*);
@ -94,9 +97,15 @@ public:
std::unique_ptr<WeakPtr> weakPtr();
int nextCallbackId();
void markFallThrough(int callbackId);
bool lastCallbackFallThrough() { return m_lastCallbackFallThrough; }
private:
FrontendChannel* m_frontendChannel;
protocol::HashSet<WeakPtr*> m_weakPtrs;
int m_lastCallbackId;
bool m_lastCallbackFallThrough;
};
class {{config.lib.export_macro}} UberDispatcher {
@ -106,10 +115,13 @@ public:
void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>);
DispatchResponse::Status dispatch(std::unique_ptr<Value> message);
FrontendChannel* channel() { return m_frontendChannel; }
bool fallThroughForNotFound() { return m_fallThroughForNotFound; }
void setFallThroughForNotFound(bool);
virtual ~UberDispatcher();
private:
FrontendChannel* m_frontendChannel;
bool m_fallThroughForNotFound;
protocol::HashMap<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers;
};

View File

@ -42,7 +42,7 @@ void ErrorSupport::addError(const String& error)
bool ErrorSupport::hasErrors()
{
return m_errors.size();
return !!m_errors.size();
}
String ErrorSupport::errors()

View File

@ -8,7 +8,6 @@
{% if config.lib.export_header %}
#include {{format_include(config.lib.export_header)}}
{% endif %}
#include {{format_include(config.lib.platform_header)}}
#include {{format_include(config.lib.string_header)}}
#include <vector>

View File

@ -10,12 +10,13 @@ namespace {{namespace}} {
std::unique_ptr<Object> Object::parse(protocol::Value* value, ErrorSupport* errors)
{
protocol::DictionaryValue* object = DictionaryValue::cast(value);
if (!object) {
protocol::DictionaryValue* dictionary = DictionaryValue::cast(value);
if (!dictionary) {
errors->addError("object expected");
return nullptr;
}
return wrapUnique(new Object(wrapUnique(static_cast<DictionaryValue*>(object->clone().release()))));
dictionary = static_cast<protocol::DictionaryValue*>(dictionary->clone().release());
return std::unique_ptr<Object>(new Object(std::unique_ptr<DictionaryValue>(dictionary)));
}
std::unique_ptr<protocol::DictionaryValue> Object::serialize() const
@ -25,7 +26,7 @@ std::unique_ptr<protocol::DictionaryValue> Object::serialize() const
std::unique_ptr<Object> Object::clone() const
{
return wrapUnique(new Object(DictionaryValue::cast(m_object->clone())));
return std::unique_ptr<Object>(new Object(DictionaryValue::cast(m_object->clone())));
}
Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { }

View File

@ -538,12 +538,12 @@ std::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length)
} // anonymous namespace
std::unique_ptr<Value> parseJSON(const uint16_t* characters, unsigned length)
std::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length)
{
return parseJSONInternal<uint16_t>(characters, length);
}
std::unique_ptr<Value> parseJSON(const uint8_t* characters, unsigned length)
std::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length)
{
return parseJSONInternal<uint8_t>(characters, length);
}

View File

@ -12,8 +12,8 @@
namespace {{namespace}} {
{% endfor %}
{{config.lib.export_macro}} std::unique_ptr<Value> parseJSON(const uint8_t*, unsigned);
{{config.lib.export_macro}} std::unique_ptr<Value> parseJSON(const uint16_t*, unsigned);
{{config.lib.export_macro}} std::unique_ptr<Value> parseJSONCharacters(const uint8_t*, unsigned);
{{config.lib.export_macro}} std::unique_ptr<Value> parseJSONCharacters(const uint16_t*, unsigned);
{% for namespace in config.protocol.namespace %}
} // namespace {{namespace}}

View File

@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "{{config.protocol.package}}/Protocol.h"
#include {{format_include(config.protocol.package, "Protocol")}}
#include <algorithm>
#include <cmath>

View File

@ -24,7 +24,7 @@ public:
static std::unique_ptr<Value> null()
{
return wrapUnique(new Value());
return std::unique_ptr<Value>(new Value());
}
enum ValueType {
@ -67,17 +67,17 @@ class {{config.lib.export_macro}} FundamentalValue : public Value {
public:
static std::unique_ptr<FundamentalValue> create(bool value)
{
return wrapUnique(new FundamentalValue(value));
return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
}
static std::unique_ptr<FundamentalValue> create(int value)
{
return wrapUnique(new FundamentalValue(value));
return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
}
static std::unique_ptr<FundamentalValue> create(double value)
{
return wrapUnique(new FundamentalValue(value));
return std::unique_ptr<FundamentalValue>(new FundamentalValue(value));
}
bool asBoolean(bool* output) const override;
@ -102,12 +102,12 @@ class {{config.lib.export_macro}} StringValue : public Value {
public:
static std::unique_ptr<StringValue> create(const String& value)
{
return wrapUnique(new StringValue(value));
return std::unique_ptr<StringValue>(new StringValue(value));
}
static std::unique_ptr<StringValue> create(const char* value)
{
return wrapUnique(new StringValue(value));
return std::unique_ptr<StringValue>(new StringValue(value));
}
bool asString(String* output) const override;
@ -125,7 +125,7 @@ class {{config.lib.export_macro}} SerializedValue : public Value {
public:
static std::unique_ptr<SerializedValue> create(const String& value)
{
return wrapUnique(new SerializedValue(value));
return std::unique_ptr<SerializedValue>(new SerializedValue(value));
}
bool asSerialized(String* output) const override;
@ -143,7 +143,7 @@ public:
using Entry = std::pair<String, Value*>;
static std::unique_ptr<DictionaryValue> create()
{
return wrapUnique(new DictionaryValue());
return std::unique_ptr<DictionaryValue>(new DictionaryValue());
}
static DictionaryValue* cast(Value* value)
@ -155,7 +155,7 @@ public:
static std::unique_ptr<DictionaryValue> cast(std::unique_ptr<Value> value)
{
return wrapUnique(DictionaryValue::cast(value.release()));
return std::unique_ptr<DictionaryValue>(DictionaryValue::cast(value.release()));
}
void writeJSON(StringBuilder* output) const override;
@ -209,7 +209,7 @@ class {{config.lib.export_macro}} ListValue : public Value {
public:
static std::unique_ptr<ListValue> create()
{
return wrapUnique(new ListValue());
return std::unique_ptr<ListValue>(new ListValue());
}
static ListValue* cast(Value* value)
@ -221,7 +221,7 @@ public:
static std::unique_ptr<ListValue> cast(std::unique_ptr<Value> value)
{
return wrapUnique(ListValue::cast(value.release()));
return std::unique_ptr<ListValue>(ListValue::cast(value.release()));
}
~ListValue() override;

View File

@ -7,8 +7,12 @@
#ifndef {{"_".join(config.protocol.namespace)}}_{{domain.domain}}_imported_h
#define {{"_".join(config.protocol.namespace)}}_{{domain.domain}}_imported_h
#include "{{config.protocol.package}}/Protocol.h"
#include {{format_include(config.imported.header if config.imported.header else "\"%s/%s.h\"" % (config.imported.package, domain.domain))}}
#include {{format_include(config.protocol.package, "Protocol")}}
{% if config.imported.header %}
#include {{format_include(config.imported.header)}}
{% else %}
#include {{format_include(config.imported.package, domain.domain)}}
{% endif %}
{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {

View File

@ -4,9 +4,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "{{config.protocol.package}}/{{domain.domain}}.h"
#include {{format_include(config.protocol.package, domain.domain)}}
#include "{{config.protocol.package}}/Protocol.h"
#include {{format_include(config.protocol.package, "Protocol")}}
{% for namespace in config.protocol.namespace %}
namespace {{namespace}} {
@ -106,7 +106,7 @@ std::unique_ptr<{{type.id}}> {{type.id}}::clone() const
std::unique_ptr<API::{{type.id}}> API::{{type.id}}::fromJSONString(const {{config.exported.string_in}}& json)
{
ErrorSupport errors;
std::unique_ptr<Value> value = parseJSON(json);
std::unique_ptr<Value> value = StringUtil::parseJSON(json);
if (!value)
return nullptr;
return protocol::{{domain.domain}}::{{type.id}}::parse(value.get(), &errors);
@ -145,9 +145,9 @@ const char* {{ literal | to_title_case}} = "{{literal}}";
// ------------- Frontend notifications.
{% for event in domain.events %}
{% if "handlers" in event and not ("renderer" in event["handlers"]) %}{% continue %}{% endif %}
{% if not generate_event(domain.domain, event.name) %}{% continue %}{% endif %}
void Frontend::{{event.name}}(
void Frontend::{{event.name | to_method_case}}(
{%- for parameter in event.parameters %}
{% if "optional" in parameter -%}
Maybe<{{resolve_type(parameter).raw_type}}>
@ -178,16 +178,22 @@ void Frontend::flush()
m_frontendChannel->flushProtocolNotifications();
}
void Frontend::sendRawNotification(const String& notification)
{
m_frontendChannel->sendProtocolNotification(notification);
}
// --------------------- Dispatcher.
class DispatcherImpl : public protocol::DispatcherBase {
public:
DispatcherImpl(FrontendChannel* frontendChannel, Backend* backend)
DispatcherImpl(FrontendChannel* frontendChannel, Backend* backend, bool fallThroughForNotFound)
: DispatcherBase(frontendChannel)
, m_backend(backend) {
, m_backend(backend)
, m_fallThroughForNotFound(fallThroughForNotFound) {
{% for command in domain.commands %}
{% if "redirect" in command %}{% continue %}{% endif %}
{% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
{% if not generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
m_dispatchMap["{{domain.domain}}.{{command.name}}"] = &DispatcherImpl::{{command.name}};
{% endfor %}
}
@ -201,17 +207,20 @@ protected:
{% for command in domain.commands %}
{% if "redirect" in command %}{% continue %}{% endif %}
{% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
{% if not generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
DispatchResponse::Status {{command.name}}(int callId, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport*);
{% endfor %}
Backend* m_backend;
bool m_fallThroughForNotFound;
};
DispatchResponse::Status DispatcherImpl::dispatch(int callId, const String& method, std::unique_ptr<protocol::DictionaryValue> messageObject)
{
protocol::HashMap<String, CallHandler>::iterator it = m_dispatchMap.find(method);
if (it == m_dispatchMap.end()) {
if (m_fallThroughForNotFound)
return DispatchResponse::kFallThrough;
reportProtocolError(callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return DispatchResponse::kError;
}
@ -222,13 +231,13 @@ DispatchResponse::Status DispatcherImpl::dispatch(int callId, const String& meth
{% for command in domain.commands %}
{% if "redirect" in command %}{% continue %}{% endif %}
{% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
{% if "async" in command %}
{% if not generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
{% if is_async_command(domain.domain, command.name) %}
class {{command.name | to_title_case}}CallbackImpl : public Backend::{{command.name | to_title_case}}Callback, public DispatcherBase::Callback {
public:
{{command.name | to_title_case}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId)
: DispatcherBase::Callback(std::move(backendImpl), callId) { }
{{command.name | to_title_case}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId)
: DispatcherBase::Callback(std::move(backendImpl), callId, callbackId) { }
void sendSuccess(
{%- for parameter in command.returns -%}
@ -252,6 +261,11 @@ public:
sendIfActive(std::move(resultObject), DispatchResponse::OK());
}
void fallThrough() override
{
fallThroughIfActive();
}
void sendFailure(const DispatchResponse& response) override
{
DCHECK(response.status() == DispatchResponse::kError);
@ -285,7 +299,7 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
return DispatchResponse::kError;
}
{% endif %}
{% if "returns" in command and not ("async" in command) %}
{% if "returns" in command and not is_async_command(domain.domain, command.name) %}
// Declare output parameters.
{% for property in command.returns %}
{% if "optional" in property %}
@ -296,9 +310,9 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
{% endfor %}
{% endif %}
{% if not("async" in command) %}
{% if not is_async_command(domain.domain, command.name) %}
std::unique_ptr<DispatcherBase::WeakPtr> weak = weakPtr();
DispatchResponse response = m_backend->{{command.name}}(
DispatchResponse response = m_backend->{{command.name | to_method_case}}(
{%- for property in command.parameters -%}
{%- if not loop.first -%}, {% endif -%}
{%- if "optional" in property -%}
@ -335,8 +349,8 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
{% endif %}
return response.status();
{% else %}
std::unique_ptr<{{command.name | to_title_case}}CallbackImpl> callback(new {{command.name | to_title_case}}CallbackImpl(weakPtr(), callId));
m_backend->{{command.name}}(
std::unique_ptr<{{command.name | to_title_case}}CallbackImpl> callback(new {{command.name | to_title_case}}CallbackImpl(weakPtr(), callId, nextCallbackId()));
m_backend->{{command.name | to_method_case}}(
{%- for property in command.parameters -%}
{%- if not loop.first -%}, {% endif -%}
{%- if "optional" in property -%}
@ -347,7 +361,7 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
{%- endfor -%}
{%- if command.parameters -%}, {% endif -%}
std::move(callback));
return DispatchResponse::kAsync;
return lastCallbackFallThrough() ? DispatchResponse::kFallThrough : DispatchResponse::kAsync;
{% endif %}
}
{% endfor %}
@ -355,7 +369,7 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
// static
void Dispatcher::wire(UberDispatcher* dispatcher, Backend* backend)
{
dispatcher->registerBackend("{{domain.domain}}", wrapUnique(new DispatcherImpl(dispatcher->channel(), backend)));
dispatcher->registerBackend("{{domain.domain}}", std::unique_ptr<protocol::DispatcherBase>(new DispatcherImpl(dispatcher->channel(), backend, dispatcher->fallThroughForNotFound())));
}
} // {{domain.domain}}

View File

@ -10,14 +10,14 @@
{% if config.protocol.export_header %}
#include {{format_include(config.protocol.export_header)}}
{% endif %}
#include "{{config.protocol.package}}/Protocol.h"
#include {{format_include(config.protocol.package, "Protocol")}}
// For each imported domain we generate a ValueConversions struct instead of a full domain definition
// and include Domain::API version from there.
{% for name in domain.dependencies %}
#include "{{config.protocol.package}}/{{name}}.h"
#include {{format_include(config.protocol.package, name)}}
{% endfor %}
{% if domain["has_exports"] %}
#include "{{config.exported.package}}/{{domain.domain}}.h"
#include {{format_include(config.exported.package, domain.domain)}}
{% endif %}
{% for namespace in config.protocol.namespace %}
@ -88,12 +88,12 @@ public:
{% endif %}
{% if property.optional %}
bool has{{property.name | to_title_case}}() { return m_{{property.name}}.isJust(); }
{{resolve_type(property).raw_return_type}} get{{property.name | to_title_case}}({{resolve_type(property).raw_pass_type}} defaultValue) { return m_{{property.name}}.isJust() ? m_{{property.name}}.fromJust() : defaultValue; }
bool {{"has" | to_method_case}}{{property.name | to_title_case}}() { return m_{{property.name}}.isJust(); }
{{resolve_type(property).raw_return_type}} {{"get" | to_method_case}}{{property.name | to_title_case}}({{resolve_type(property).raw_pass_type}} defaultValue) { return m_{{property.name}}.isJust() ? m_{{property.name}}.fromJust() : defaultValue; }
{% else %}
{{resolve_type(property).raw_return_type}} get{{property.name | to_title_case}}() { return {{resolve_type(property).to_raw_type % ("m_" + property.name)}}; }
{{resolve_type(property).raw_return_type}} {{"get" | to_method_case}}{{property.name | to_title_case}}() { return {{resolve_type(property).to_raw_type % ("m_" + property.name)}}; }
{% endif %}
void set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value) { m_{{property.name}} = {{resolve_type(property).to_rvalue % "value"}}; }
void {{"set" | to_method_case}}{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value) { m_{{property.name}} = {{resolve_type(property).to_rvalue % "value"}}; }
{% endfor %}
std::unique_ptr<protocol::DictionaryValue> serialize() const;
@ -122,22 +122,22 @@ public:
{% 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" | to_method_case}}{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value)
{
m_result->set{{property.name | to_title_case}}({{resolve_type(property).to_rvalue % "value"}});
m_result->{{"set" | to_method_case}}{{property.name | to_title_case}}({{resolve_type(property).to_rvalue % "value"}});
return *this;
}
{% else %}
{{type.id}}Builder<STATE | {{property.name | to_title_case}}Set>& set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value)
{{type.id}}Builder<STATE | {{property.name | to_title_case}}Set>& {{"set" | to_method_case}}{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value)
{
static_assert(!(STATE & {{property.name | to_title_case}}Set), "property {{property.name}} should not be set yet");
m_result->set{{property.name | to_title_case}}({{resolve_type(property).to_rvalue % "value"}});
m_result->{{"set" | to_method_case}}{{property.name | to_title_case}}({{resolve_type(property).to_rvalue % "value"}});
return castState<{{property.name | to_title_case}}Set>();
}
{% endif %}
{% endfor %}
std::unique_ptr<{{type.id}}> build()
std::unique_ptr<{{type.id}}> {{"build" | to_method_case}}()
{
static_assert(STATE == AllFieldsSet, "state should be AllFieldsSet");
return std::move(m_result);
@ -155,7 +155,7 @@ public:
{{type_def.type}} m_result;
};
static {{type.id}}Builder<0> create()
static {{type.id}}Builder<0> {{"create" | to_method_case}}()
{
return {{type.id}}Builder<0>();
}
@ -189,8 +189,8 @@ public:
{% for command in domain.commands %}
{% if "redirect" in command %}{% continue %}{% endif %}
{% if ("handlers" in command) and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
{% if "async" in command %}
{% if not generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
{% if is_async_command(domain.domain, command.name) %}
class {{config.protocol.export_macro}} {{command.name | to_title_case}}Callback {
public:
virtual void sendSuccess(
@ -204,13 +204,14 @@ public:
{%- endfor -%}
) = 0;
virtual void sendFailure(const DispatchResponse&) = 0;
virtual void fallThrough() = 0;
virtual ~{{command.name | to_title_case}}Callback() { }
};
{% endif %}
{%- if not("async" in command) %}
virtual DispatchResponse {{command.name}}(
{%- if not is_async_command(domain.domain, command.name) %}
virtual DispatchResponse {{command.name | to_method_case}}(
{%- else %}
virtual void {{command.name}}(
virtual void {{command.name | to_method_case}}(
{%- endif %}
{%- for parameter in command.parameters -%}
{%- if not loop.first -%}, {% endif -%}
@ -220,7 +221,7 @@ public:
{{resolve_type(parameter).pass_type}} in_{{parameter.name}}
{%- endif -%}
{%- endfor -%}
{%- if "async" in command -%}
{%- if is_async_command(domain.domain, command.name) -%}
{%- if command.parameters -%}, {% endif -%}
std::unique_ptr<{{command.name | to_title_case}}Callback> callback
{%- else -%}
@ -236,8 +237,8 @@ public:
) = 0;
{% endfor %}
{% if not has_disable(domain.commands) %}
virtual DispatchResponse disable()
{% if generate_disable(domain) %}
virtual DispatchResponse {{"disable" | to_method_case}}()
{
return DispatchResponse::OK();
}
@ -248,10 +249,10 @@ public:
class {{config.protocol.export_macro}} Frontend {
public:
Frontend(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
explicit Frontend(FrontendChannel* frontendChannel) : m_frontendChannel(frontendChannel) { }
{% for event in domain.events %}
{% if "handlers" in event and not ("renderer" in event["handlers"]) %}{% continue %}{% endif %}
void {{event.name}}(
{% if not generate_event(domain.domain, event.name) %}{% continue %}{% endif %}
void {{event.name | to_method_case}}(
{%- for parameter in event.parameters -%}
{%- if "optional" in parameter -%}
Maybe<{{resolve_type(parameter).raw_type}}> {{parameter.name}} = Maybe<{{resolve_type(parameter).raw_type}}>()
@ -263,6 +264,7 @@ public:
{% endfor %}
void flush();
void sendRawNotification(const String&);
private:
FrontendChannel* m_frontendChannel;
};