summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/CodeGeneratorInspector.pm
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/inspector/CodeGeneratorInspector.pm')
-rw-r--r--WebCore/inspector/CodeGeneratorInspector.pm267
1 files changed, 183 insertions, 84 deletions
diff --git a/WebCore/inspector/CodeGeneratorInspector.pm b/WebCore/inspector/CodeGeneratorInspector.pm
index 5488dbd..9d0af53 100644
--- a/WebCore/inspector/CodeGeneratorInspector.pm
+++ b/WebCore/inspector/CodeGeneratorInspector.pm
@@ -14,9 +14,33 @@ $typeTransform{"InspectorClient"} = {
"forward" => "InspectorClient",
"header" => "InspectorClient.h",
};
-$typeTransform{"InspectorBackend"} = {
+$typeTransform{"Backend"} = {
"forward" => "InspectorBackend",
"header" => "InspectorBackend.h",
+ "handlerAccessor" => "m_inspectorController->inspectorBackend()",
+};
+$typeTransform{"Controller"} = {
+ "forwardHeader" => "InspectorController.h",
+ "handlerAccessor" => "m_inspectorController",
+};
+$typeTransform{"Debug"} = {
+ "forward" => "InspectorDebuggerAgent",
+ "header" => "InspectorDebuggerAgent.h",
+ "handlerAccessor" => "m_inspectorController->debuggerAgent()",
+};
+$typeTransform{"DOM"} = {
+ "forward" => "InspectorDOMAgent",
+ "header" => "InspectorDOMAgent.h",
+ "handlerAccessor" => "m_inspectorController->domAgent()",
+};
+$typeTransform{"ApplicationCache"} = {
+ "forward" => "InspectorApplicationCacheAgent",
+ "header" => "InspectorApplicationCacheAgent.h",
+ "handlerAccessor" => "m_inspectorController->applicationCacheAgent()",
+};
+$typeTransform{"Frontend"} = {
+ "forward" => "RemoteInspectorFrontend",
+ "header" => "RemoteInspectorFrontend.h",
};
$typeTransform{"PassRefPtr"} = {
"forwardHeader" => "wtf/PassRefPtr.h",
@@ -24,6 +48,8 @@ $typeTransform{"PassRefPtr"} = {
$typeTransform{"Object"} = {
"param" => "PassRefPtr<InspectorObject>",
"retVal" => "PassRefPtr<InspectorObject>",
+ "variable" => "RefPtr<InspectorObject>",
+ "defaultValue" => "InspectorObject::create()",
"forward" => "InspectorObject",
"header" => "InspectorValues.h",
"accessorSuffix" => ""
@@ -31,6 +57,8 @@ $typeTransform{"Object"} = {
$typeTransform{"Array"} = {
"param" => "PassRefPtr<InspectorArray>",
"retVal" => "PassRefPtr<InspectorArray>",
+ "variable" => "RefPtr<InspectorArray>",
+ "defaultValue" => "InspectorArray::create()",
"forward" => "InspectorArray",
"header" => "InspectorValues.h",
"accessorSuffix" => ""
@@ -38,41 +66,55 @@ $typeTransform{"Array"} = {
$typeTransform{"Value"} = {
"param" => "PassRefPtr<InspectorValue>",
"retVal" => "PassRefPtr<InspectorValue>",
+ "variable" => "RefPtr<InspectorValue>",
+ "defaultValue" => "InspectorValue::null()",
"forward" => "InspectorValue",
"header" => "InspectorValues.h",
"accessorSuffix" => ""
};
$typeTransform{"String"} = {
"param" => "const String&",
- "retVal" => "String",
- "forward" => "String",
+ "variable" => "String",
+ "forwardHeader" => "wtf/Forward.h",
"header" => "PlatformString.h",
"accessorSuffix" => "String"
};
$typeTransform{"long"} = {
"param" => "long",
- "retVal" => "long",
+ "variable" => "long",
+ "defaultValue" => "0",
"forward" => "",
"header" => "",
"accessorSuffix" => "Number"
};
$typeTransform{"int"} = {
"param" => "int",
- "retVal" => "int",
+ "variable" => "int",
+ "defaultValue" => "0",
"forward" => "",
"header" => "",
"accessorSuffix" => "Number",
};
$typeTransform{"unsigned long"} = {
"param" => "unsigned long",
- "retVal" => "unsigned long",
+ "variable" => "unsigned long",
+ "defaultValue" => "0u",
+ "forward" => "",
+ "header" => "",
+ "accessorSuffix" => "Number"
+};
+$typeTransform{"unsigned int"} = {
+ "param" => "unsigned int",
+ "variable" => "unsigned int",
+ "defaultValue" => "0u",
"forward" => "",
"header" => "",
"accessorSuffix" => "Number"
};
$typeTransform{"boolean"} = {
"param" => "bool",
- "retVal"=> "bool",
+ "variable"=> "bool",
+ "defaultValue" => "false",
"forward" => "",
"header" => "",
"accessorSuffix" => "Bool"
@@ -163,12 +205,14 @@ sub GenerateInterface
$backendClassName = $className . "BackendDispatcher";
my @backendHead;
- push(@backendHead, " ${backendClassName}(InspectorBackend* inspectorBackend) : m_inspectorBackend(inspectorBackend) { }");
+ push(@backendHead, " ${backendClassName}(InspectorController* inspectorController) : m_inspectorController(inspectorController) { }");
+ push(@backendHead, " void reportProtocolError(const long callId, const String& method, const String& errorText) const;");
push(@backendHead, " void dispatch(const String& message);");
push(@backendHead, "private:");
$backendConstructor = join("\n", @backendHead);
- $backendFooter = " InspectorBackend* m_inspectorBackend;";
- $backendTypes{"InspectorBackend"} = 1;
+ $backendFooter = " InspectorController* m_inspectorController;";
+ $backendTypes{"Controller"} = 1;
+ $backendTypes{"InspectorClient"} = 1;
$backendTypes{"PassRefPtr"} = 1;
$backendTypes{"Array"} = 1;
@@ -185,20 +229,16 @@ sub generateFunctions
generateBackendFunction($function);
}
push(@backendMethodsImpl, generateBackendDispatcher());
+ push(@backendMethodsImpl, generateBackendReportProtocolError());
}
sub generateFrontendFunction
{
my $function = shift;
- my $functionName;
my $notify = $function->signature->extendedAttributes->{"notify"};
- if ($notify) {
- $functionName = $function->signature->name;
- } else {
- my $customResponse = $function->signature->extendedAttributes->{"customResponse"};
- $functionName = $customResponse ? $customResponse : "did" . ucfirst($function->signature->name);
- }
+ return if !$notify;
+ my $functionName = $notify ? $function->signature->name : "did" . ucfirst($function->signature->name);
my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface.
unshift(@argsFiltered, $callId) if !$notify; # Add callId as the first argument for all frontend did* methods.
@@ -214,9 +254,10 @@ sub generateFrontendFunction
push(@function, "void ${frontendClassName}::${functionName}(${arguments})");
push(@function, "{");
push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();");
- push(@function, " arguments->pushString(\"$functionName\");");
+ push(@function, " arguments->pushString(\"" . ($notify ? $functionName : "processResponse") . "\");");
push(@function, @pushArguments);
push(@function, " m_inspectorClient->sendMessageToFrontend(arguments->toJSONString());");
+
push(@function, "}");
push(@function, "");
push(@frontendMethodsImpl, @function);
@@ -228,12 +269,12 @@ sub generateBackendPrivateFunctions
my $privateFunctions = << "EOF";
static String formatWrongArgumentsCountMessage(unsigned expected, unsigned actual)
{
- return String::format(\"Wrong number of parameters: %d (expected: %d)\", actual, expected);
+ return String::format("Wrong number of parameters: %d (expected: %d)", actual, expected);
}
static String formatWrongArgumentTypeMessage(unsigned position, const char* name, const char* expectedType)
{
- return String::format(\"Failed to convert parameter %d (%s) to %s\", position, name, expectedType);
+ return String::format("Failed to convert parameter %d (%s) to %s", position, name, expectedType);
}
EOF
push(@backendMethodsImpl, $privateFunctions);
@@ -246,95 +287,153 @@ sub generateBackendFunction
my $functionName = $function->signature->name;
- my @argsFiltered = grep($_->direction eq "in", @{$function->parameters});
- map($backendTypes{$_->type} = 1, @argsFiltered); # register required types
- my $arguments = join(", ", map($typeTransform{$_->type}->{"param"} . " " . $_->name, @argsFiltered));
+ map($backendTypes{$_->type} = 1, @{$function->parameters}); # register required types
+ my @inArgs = grep($_->direction eq "in", @{$function->parameters});
+ my @outArgs = grep($_->direction eq "out", @{$function->parameters});
- my $signature = " void ${functionName}(PassRefPtr<InspectorArray> args, String* exception);";
+ my $signature = " void ${functionName}(PassRefPtr<InspectorArray> args);";
!$backendMethods{${signature}} || die "Duplicate function was detected for signature '$signature'.";
$backendMethods{${signature}} = $functionName;
my @function;
- push(@function, "void ${backendClassName}::${functionName}(PassRefPtr<InspectorArray> args, String* exception)");
+ push(@function, "void ${backendClassName}::${functionName}(PassRefPtr<InspectorArray> args)");
push(@function, "{");
- my $i = 1; # zero element is the method name.
- my $expectedParametersCount = scalar(@argsFiltered);
- my $expectedParametersCountWithMethodName = scalar(@argsFiltered) + 1;
+ push(@function, " DEFINE_STATIC_LOCAL(String, backendFunctionName, (\"$functionName\"));");
+ push(@function, " long callId = 0;");
+ push(@function, "");
+
+ my $expectedParametersCount = scalar(@inArgs);
+ my $expectedParametersCountWithMethodName = scalar(@inArgs) + 1;
push(@function, " if (args->length() != $expectedParametersCountWithMethodName) {");
- push(@function, " *exception = formatWrongArgumentsCountMessage(args->length() - 1, $expectedParametersCount);");
push(@function, " ASSERT_NOT_REACHED();");
+ push(@function, " reportProtocolError(callId, backendFunctionName, formatWrongArgumentsCountMessage(args->length() - 1, $expectedParametersCount));");
push(@function, " return;");
push(@function, " }");
+ push(@function, "");
- foreach my $parameter (@argsFiltered) {
- my $parameterType = $parameter->type;
- push(@function, " " . $typeTransform{$parameterType}->{"retVal"} . " " . $parameter->name . ";");
- push(@function, " if (!args->get(" . $i . ")->as" . $typeTransform{$parameterType}->{"accessorSuffix"} . "(&" . $parameter->name . ")) {");
- push(@function, " *exception = formatWrongArgumentTypeMessage($i, \"" . $parameter->name . "\", \"$parameterType\");");
+ my $i = 1; # zero element is the method name.
+ foreach my $parameter (@inArgs) {
+ my $type = $parameter->type;
+ my $argumentType = $typeTransform{$type}->{$typeTransform{$type}->{"retVal"} ? "retVal" : "variable"};
+ push(@function, " $argumentType " . $parameter->name . ";") if !($parameter->name eq "callId");
+ push(@function, " if (!args->get($i)->as" . $typeTransform{$type}->{"accessorSuffix"} . "(&" . $parameter->name . ")) {");
push(@function, " ASSERT_NOT_REACHED();");
+ push(@function, " reportProtocolError(callId, backendFunctionName, formatWrongArgumentTypeMessage($i, \"" . $parameter->name . "\", \"$type\"));");
push(@function, " return;");
push(@function, " }");
+ push(@function, "");
++$i;
}
- push(@function, " m_inspectorBackend->$functionName(" . join(", ", map($_->name, @argsFiltered)) . ");");
+
+ my $handler = $function->signature->extendedAttributes->{"handler"} || "Controller";
+ my $handlerAccessor = $typeTransform{$handler}->{"handlerAccessor"};
+ $backendTypes{$handler} = 1;
+ push(@function, " if (!$handlerAccessor) {");
+ push(@function, " reportProtocolError(callId, backendFunctionName, \"Error: $handler handler is not available.\");");
+ push(@function, " return;");
+ push(@function, " }");
+ push(@function, "");
+
+
+ foreach (@outArgs) { # declare local variables for out arguments.
+ my $initializer = $typeTransform{$_->type}->{"defaultValue"} ? " = " . $typeTransform{$_->type}->{"defaultValue"} : "";
+ push(@function, " " . $typeTransform{$_->type}->{"variable"} . " " . $_->name . "$initializer;");
+ }
+
+ my $args = join(", ", (grep(!($_ eq "callId"), map($_->name, @inArgs)), map("&" . $_->name, @outArgs)));
+ push(@function, " $handlerAccessor->$functionName($args);");
+
+ # The results of function call should be transfered back to frontend.
+ if (scalar(grep($_->name eq "callId", @inArgs))) {
+ my @pushArguments = map(" arguments->push" . $typeTransform{$_->type}->{"accessorSuffix"} . "(" . $_->name . ");", @outArgs);
+
+ push(@function, "");
+ push(@function, " // use InspectorFrontend as a marker of WebInspector availability");
+ push(@function, " if (m_inspectorController->hasFrontend()) {");
+ push(@function, " RefPtr<InspectorArray> arguments = InspectorArray::create();");
+ push(@function, " arguments->pushString(\"processResponse\");");
+ push(@function, " arguments->pushNumber(callId);");
+ push(@function, @pushArguments);
+ push(@function, " m_inspectorController->inspectorClient()->sendMessageToFrontend(arguments->toJSONString());");
+ push(@function, " }");
+ }
push(@function, "}");
push(@function, "");
push(@backendMethodsImpl, @function);
}
+sub generateBackendReportProtocolError
+{
+ my $reportProtocolError = << "EOF";
+
+void ${backendClassName}::reportProtocolError(const long callId, const String& method, const String& errorText) const
+{
+ RefPtr<InspectorArray> arguments = InspectorArray::create();
+ arguments->pushString("reportProtocolError");
+ arguments->pushNumber(callId);
+ arguments->pushString(method);
+ arguments->pushString(errorText);
+ m_inspectorController->inspectorClient()->sendMessageToFrontend(arguments->toJSONString());
+}
+EOF
+ return split("\n", $reportProtocolError);
+}
+
sub generateBackendDispatcher
{
my @body;
my @methods = map($backendMethods{$_}, keys %backendMethods);
- my @mapEntries = map("dispatchMap.add(\"$_\", &${backendClassName}::$_);", @methods);
-
- push(@body, "void ${backendClassName}::dispatch(const String& message)");
- push(@body, "{");
- push(@body, " String exception;");
- push(@body, " typedef void (${backendClassName}::*CallHandler)(PassRefPtr<InspectorArray> args, String* exception);");
- push(@body, " typedef HashMap<String, CallHandler> DispatchMap;");
- push(@body, " DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );");
- push(@body, " if (dispatchMap.isEmpty()) {");
- push(@body, map(" $_", @mapEntries));
- push(@body, " }");
- push(@body, "");
- push(@body, " RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);");
- push(@body, " if (!parsedMessage) {");
- push(@body, " ASSERT_NOT_REACHED();");
- push(@body, " exception = \"Error: Invalid message format. Message should be in JSON format.\";");
- push(@body, " return;");
- push(@body, " }");
- push(@body, "");
- push(@body, " RefPtr<InspectorArray> messageArray = parsedMessage->asArray();");
- push(@body, " if (!messageArray) {");
- push(@body, " ASSERT_NOT_REACHED();");
- push(@body, " exception = \"Error: Invalid message format. The message should be a JSONified array of arguments.\";");
- push(@body, " return;");
- push(@body, " }");
- push(@body, "");
- push(@body, " if (!messageArray->length()) {");
- push(@body, " ASSERT_NOT_REACHED();");
- push(@body, " exception = \"Error: Invalid message format. Empty message was received.\";");
- push(@body, " return;");
- push(@body, " }");
- push(@body, "");
- push(@body, " String methodName;");
- push(@body, " if (!messageArray->get(0)->asString(&methodName)) {");
- push(@body, " ASSERT_NOT_REACHED();");
- push(@body, " exception = \"Error: Invalid message format. The first element of the message should be method name.\";");
- push(@body, " return;");
- push(@body, " }");
- push(@body, "");
- push(@body, " HashMap<String, CallHandler>::iterator it = dispatchMap.find(methodName);");
- push(@body, " if (it == dispatchMap.end()) {");
- push(@body, " ASSERT_NOT_REACHED();");
- push(@body, " exception = String::format(\"Error: Invalid method name. '%s' wasn't found.\", methodName.utf8().data());");
- push(@body, " return;");
- push(@body, " }");
- push(@body, "");
- push(@body, " ((*this).*it->second)(messageArray, &exception);");
- push(@body, "}");
- return @body;
+ my @mapEntries = map(" dispatchMap.add(\"$_\", &${backendClassName}::$_);", @methods);
+ my $mapEntries = join("\n", @mapEntries);
+
+ my $backendDispatcherBody = << "EOF";
+void ${backendClassName}::dispatch(const String& message)
+{
+ typedef void (${backendClassName}::*CallHandler)(PassRefPtr<InspectorArray> args);
+ typedef HashMap<String, CallHandler> DispatchMap;
+ DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
+ if (dispatchMap.isEmpty()) {
+$mapEntries
+ }
+
+ RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
+ if (!parsedMessage) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(0, "dispatch", "Error: Invalid message format. Message should be in JSON format.");
+ return;
+ }
+
+ RefPtr<InspectorArray> messageArray = parsedMessage->asArray();
+ if (!messageArray) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(0, "dispatch", "Error: Invalid message format. The message should be a JSONified array of arguments.");
+ return;
+ }
+
+ if (!messageArray->length()) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(0, "dispatch", "Error: Invalid message format. Empty message was received.");
+ return;
+ }
+
+ String methodName;
+ if (!messageArray->get(0)->asString(&methodName)) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(0, "dispatch", "Error: Invalid message format. The first element of the message should be method name.");
+ return;
+ }
+
+ HashMap<String, CallHandler>::iterator it = dispatchMap.find(methodName);
+ if (it == dispatchMap.end()) {
+ ASSERT_NOT_REACHED();
+ reportProtocolError(0, "dispatch", String::format("Error: Invalid method name. '%s' wasn't found.", methodName.utf8().data()));
+ return;
+ }
+
+ ((*this).*it->second)(messageArray);
+}
+EOF
+ return split("\n", $backendDispatcherBody);
}
sub generateHeader