Web Inspector: reimplement protocol backend/frontend source generator
authorloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Oct 2011 06:00:34 +0000 (06:00 +0000)
committerloislo@chromium.org <loislo@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Oct 2011 06:00:34 +0000 (06:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=69295

Patch by Peter Rybin <peter.rybin@gmail.com> on 2011-10-20
Reviewed by Pavel Feldman.

Old 2-stage python+perf generator that uses intermediate IDL output is
being replaced with a solid python script. This is for simplicity and
as a base for the future JSON validator.

* CMakeLists.txt:
* CodeGenerators.pri:
* DerivedSources.make:
* GNUmakefile.am:
* WebCore.gyp/WebCore.gyp:
* inspector/CodeGeneratorInspector.pm: Removed.
* inspector/CodeGeneratorInspector.py: Added.
* inspector/Inspector.json:
* inspector/generate-inspector-idl: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@98069 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/CodeGenerators.pri
Source/WebCore/DerivedSources.make
Source/WebCore/GNUmakefile.am
Source/WebCore/WebCore.gyp/WebCore.gyp
Source/WebCore/inspector/CodeGeneratorInspector.pm [deleted file]
Source/WebCore/inspector/CodeGeneratorInspector.py [new file with mode: 0644]
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/generate-inspector-idl [deleted file]

index a2fc5bb0e003b21b785c363b03fcf76361c2c89c..5fbca32cfcb8925b7f3c8b9e17e309d7dfb5fb4c 100644 (file)
@@ -2220,18 +2220,11 @@ ADD_CUSTOM_COMMAND(
     VERBATIM)
 LIST(APPEND WebCore_SOURCES ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorProtocolVersion.h)
 
-ADD_CUSTOM_COMMAND(
-    OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/Inspector.idl
-    MAIN_DEPENDENCY inspector/Inspector.json
-    DEPENDS ${WEBCORE_DIR}/inspector/generate-inspector-idl ${WEBCORE_DIR}/inspector/Inspector.json
-    COMMAND ${PYTHON_EXECUTABLE} ${WEBCORE_DIR}/inspector/generate-inspector-idl -o ${DERIVED_SOURCES_WEBCORE_DIR}/Inspector.idl ${WEBCORE_DIR}/inspector/Inspector.json
-    VERBATIM)
-
 ADD_CUSTOM_COMMAND(
     OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorBackendDispatcher.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorBackendDispatcher.h ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorFrontend.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorFrontend.h
-    MAIN_DEPENDENCY ${DERIVED_SOURCES_WEBCORE_DIR}/Inspector.idl
-    DEPENDS ${WEBCORE_DIR}/bindings/scripts/generate-bindings.pl ${SCRIPTS_BINDINGS} ${WEBCORE_DIR}/inspector/CodeGeneratorInspector.pm ${DERIVED_SOURCES_WEBCORE_DIR}/Inspector.idl
-    COMMAND ${PERL_EXECUTABLE} -I${WEBCORE_DIR}/bindings/scripts -I${WEBCORE_DIR}/inspector ${WEBCORE_DIR}/bindings/scripts/generate-bindings.pl --defines "${FEATURE_DEFINES_JAVASCRIPT}" --generator Inspector ${IDL_INCLUDES} --outputDir "${DERIVED_SOURCES_WEBCORE_DIR}" --preprocessor "${CODE_GENERATOR_PREPROCESSOR}" ${DERIVED_SOURCES_WEBCORE_DIR}/Inspector.idl
+    MAIN_DEPENDENCY inspector/Inspector.json
+    DEPENDS ${WEBCORE_DIR}/inspector/CodeGeneratorInspector.py
+    COMMAND ${PYTHON_EXECUTABLE} ${WEBCORE_DIR}/inspector/CodeGeneratorInspector.py ${WEBCORE_DIR}/inspector/Inspector.json --output_h_dir "${DERIVED_SOURCES_WEBCORE_DIR}" --output_cpp_dir "${DERIVED_SOURCES_WEBCORE_DIR}" --defines "${FEATURE_DEFINES_JAVASCRIPT}"
     VERBATIM)
 LIST(APPEND WebCore_SOURCES ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorBackendDispatcher.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/InspectorFrontend.cpp)
 
index ff1cdd8ba316974f339d93a6e9dab258feaba80c..2ea2fc9a2c03384104d08eef91434585e3e3b41a 100755 (executable)
@@ -1,3 +1,24 @@
+2011-10-20  Peter Rybin  <peter.rybin@gmail.com>
+
+        Web Inspector: reimplement protocol backend/frontend source generator
+        https://bugs.webkit.org/show_bug.cgi?id=69295
+
+        Reviewed by Pavel Feldman.
+
+        Old 2-stage python+perf generator that uses intermediate IDL output is
+        being replaced with a solid python script. This is for simplicity and
+        as a base for the future JSON validator.
+
+        * CMakeLists.txt:
+        * CodeGenerators.pri:
+        * DerivedSources.make:
+        * GNUmakefile.am:
+        * WebCore.gyp/WebCore.gyp:
+        * inspector/CodeGeneratorInspector.pm: Removed.
+        * inspector/CodeGeneratorInspector.py: Added.
+        * inspector/Inspector.json:
+        * inspector/generate-inspector-idl: Removed.
+
 2011-10-20  Adam Barth  <abarth@webkit.org>
 
         Attemp to fix a bunch of tests PLATFORM(MAC).  We can't use a static
index b972dc715e3938ff827fe05cf993914ea4241443..feebba0c552b39b046b16ead5a6b4c4d0a0fe5f6 100644 (file)
@@ -683,29 +683,12 @@ inspectorValidate.depends = $$PWD/inspector/generate-inspector-protocol-version
 inspectorValidate.wkAddOutputToSources = false
 addExtraCompiler(inspectorValidate)
 
-inspectorJSON.output = $${WC_GENERATED_SOURCES_DIR}/Inspector.idl
+inspectorJSON.output = $${WC_GENERATED_SOURCES_DIR}/InspectorFrontend.cpp $${WC_GENERATED_SOURCES_DIR}/InspectorBackendDispatcher.cpp
 inspectorJSON.input = INSPECTOR_JSON
-inspectorJSON.wkScript = $$PWD/inspector/generate-inspector-idl
-inspectorJSON.commands = python $$inspectorJSON.wkScript -o $${WC_GENERATED_SOURCES_DIR}/Inspector.idl $$PWD/inspector/Inspector.json
-inspectorJSON.depends = $$PWD/inspector/generate-inspector-idl
-inspectorJSON.wkAddOutputToSources = false
+inspectorJSON.wkScript = $$PWD/inspector/CodeGeneratorInspector.py
+inspectorJSON.commands = python $$inspectorJSON.wkScript $$PWD/inspector/Inspector.json --output_h_dir $$WC_GENERATED_SOURCES_DIR --output_cpp_dir $$WC_GENERATED_SOURCES_DIR --defines \"$${FEATURE_DEFINES_JAVASCRIPT}\"
+inspectorJSON.depends = $$inspectorJSON.wkScript
 addExtraCompiler(inspectorJSON)
-inspectorJSON.variable_out = INSPECTOR_JSON_OUTPUT
-
-inspectorIDL.output = $${WC_GENERATED_SOURCES_DIR}/InspectorFrontend.cpp $${WC_GENERATED_SOURCES_DIR}/InspectorBackendDispatcher.cpp
-inspectorIDL.input = INSPECTOR_JSON_OUTPUT
-inspectorIDL.wkScript = $$PWD/bindings/scripts/generate-bindings.pl
-inspectorIDL.commands = perl -I$$PWD/bindings/scripts -I$$PWD/inspector $$inspectorIDL.wkScript --defines \"$${FEATURE_DEFINES_JAVASCRIPT}\" --generator Inspector --outputDir $$WC_GENERATED_SOURCES_DIR --preprocessor \"$${QMAKE_MOC} -E\" ${QMAKE_FILE_NAME}
-inspectorIDL.depends = $$PWD/bindings/scripts/CodeGenerator.pm \
-              $$PWD/inspector/CodeGeneratorInspector.pm \
-              $$PWD/bindings/scripts/IDLParser.pm \
-              $$PWD/bindings/scripts/IDLStructure.pm \
-              $$PWD/bindings/scripts/InFilesParser.pm \
-              $$PWD/bindings/scripts/preprocessor.pm \
-              $$PWD/inspector/Inspector.json \
-              $$PWD/inspector/generate-inspector-idl
-inspectorIDL.wkExtraSources = $$inspectorIDL.output
-addExtraCompiler(inspectorIDL)
 
 inspectorBackendStub.output = generated/InspectorBackendStub.qrc
 inspectorBackendStub.input = INSPECTOR_BACKEND_STUB_QRC
index 5a2cc13f8f136cf080a411ae0eb1b005bff77efd..2d972e577633f366262736feb77650ec19f78d3a 100644 (file)
@@ -912,15 +912,12 @@ all : InspectorProtocolVersion.h
 InspectorProtocolVersion.h : Inspector.json inspector/generate-inspector-protocol-version
        python $(WebCore)/inspector/generate-inspector-protocol-version -o InspectorProtocolVersion.h $(WebCore)/inspector/Inspector.json
 
-Inspector.idl : Inspector.json inspector/generate-inspector-idl
-       python $(WebCore)/inspector/generate-inspector-idl -o Inspector.idl $(WebCore)/inspector/Inspector.json
-
 all : InspectorFrontend.h
 
-INSPECTOR_GENERATOR_SCRIPTS = $(GENERATE_SCRIPTS) inspector/CodeGeneratorInspector.pm
+INSPECTOR_GENERATOR_SCRIPTS = inspector/CodeGeneratorInspector.py
 
-InspectorFrontend.h : Inspector.idl $(INSPECTOR_GENERATOR_SCRIPTS)
-       $(call generator_script, $(INSPECTOR_GENERATOR_SCRIPTS)) --outputDir . --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT" --generator Inspector $<
+InspectorFrontend.h : Inspector.json $(INSPECTOR_GENERATOR_SCRIPTS)
+       python $(WebCore)/inspector/CodeGeneratorInspector.py $(WebCore)/inspector/Inspector.json --output_h_dir . --output_cpp_dir . --defines "$(FEATURE_DEFINES) LANGUAGE_JAVASCRIPT"
 
 all : InjectedScriptSource.h
 
index 7e492c81b69783af539b008c199a307747d12e2e..c78baf96308e356ed16d36d1c3a3dba3128d2b25 100644 (file)
@@ -688,11 +688,8 @@ DerivedSources/WebCore/EventFactory.cpp DerivedSources/WebCore/EventHeaders.h De
 DerivedSources/WebCore/InspectorProtocolVersion.h : $(WebCore)/inspector/Inspector.json $(WebCore)/inspector/generate-inspector-protocol-version
        $(PYTHON) $(WebCore)/inspector/generate-inspector-protocol-version -o $(GENSOURCES_WEBCORE)/InspectorProtocolVersion.h $(WebCore)/inspector/Inspector.json
 
-DerivedSources/WebCore/Inspector.idl : $(WebCore)/inspector/Inspector.json $(WebCore)/inspector/generate-inspector-idl
-       $(PYTHON) $(WebCore)/inspector/generate-inspector-idl -o $(GENSOURCES_WEBCORE)/Inspector.idl $(WebCore)/inspector/Inspector.json
-
-DerivedSources/WebCore/InspectorBackendDispatcher.cpp: DerivedSources/WebCore/Inspector.idl $(SCRIPTS_BINDINGS) $(WebCore)/inspector/CodeGeneratorInspector.pm
-       $(AM_V_GEN)$(PERL) -I$(WebCore)/bindings/scripts -I$(WebCore)/inspector $(WebCore)/bindings/scripts/generate-bindings.pl $(IDL_PATH:%=--include "%") --outputDir "$(GENSOURCES_WEBCORE)" --defines "LANGUAGE_JAVASCRIPT=1 $(FEATURE_DEFINES)" --generator Inspector $<
+DerivedSources/WebCore/InspectorBackendDispatcher.cpp: $(WebCore)/inspector/Inspector.json $(WebCore)/inspector/CodeGeneratorInspector.py
+       $(PYTHON) $(WebCore)/inspector/CodeGeneratorInspector.py $< --output_h_dir $(GENSOURCES_WEBCORE) --output_cpp_dir $(GENSOURCES_WEBCORE) --defines "LANGUAGE_JAVASCRIPT=1 $(FEATURE_DEFINES)"
 DerivedSources/WebCore/InspectorFrontend.h: DerivedSources/WebCore/InspectorFrontend.cpp
 DerivedSources/WebCore/InspectorFrontend.cpp: DerivedSources/WebCore/InspectorBackendStub.js
 DerivedSources/WebCore/InspectorBackendStub.js: DerivedSources/WebCore/InspectorBackendDispatcher.h
index d79f65eb8c1981fd09d19ceaff3f9802b19db766..4ce84037d00f32b013c782d633e15df16b3a8340 100644 (file)
   },
   'targets': [
     {
-      'target_name': 'generate_inspector_protocol_version',
+      'target_name': 'inspector_protocol_sources',
       'type': 'none',
+      'dependencies': [
+        'generate_inspector_protocol_version'
+      ],
       'actions': [
-         {
-          'action_name': 'generateInspectorProtocolVersion',
+        {
+          'action_name': 'generateInspectorProtocolSources',
           'inputs': [
-            '../inspector/generate-inspector-protocol-version',
+            # First input. It stands for python script in action below.
+            '../inspector/CodeGeneratorInspector.py',
+            # Other inputs. They go as arguments to the python script.
             '../inspector/Inspector.json',
           ],
           'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorProtocolVersion.h',
+            '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendDispatcher.cpp',
+            '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorBackendDispatcher.h',
+            '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorFrontend.cpp',
+            '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorFrontend.h',
+            '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendStub.js',
           ],
           'variables': {
             'generator_include_dirs': [
           },
           'action': [
             'python',
-            '../inspector/generate-inspector-protocol-version',
-            '-o',
-            '<@(_outputs)',
-            '<@(_inputs)'
+            '<@(_inputs)',
+            '--output_h_dir', '<(SHARED_INTERMEDIATE_DIR)/webkit',
+            '--output_cpp_dir', '<(SHARED_INTERMEDIATE_DIR)/webcore',
+            '--defines', '<(feature_defines) LANGUAGE_JAVASCRIPT',
           ],
-          'message': 'Validate inspector protocol for backwards compatibility and generate version file',
-        }
+          'message': 'Generating Inspector protocol sources from Inspector.json',
+        },
       ]
     },
     {
-      'target_name': 'inspector_idl',
+      'target_name': 'generate_inspector_protocol_version',
       'type': 'none',
       'actions': [
-
-        {
-          'action_name': 'generateInspectorProtocolIDL',
+         {
+          'action_name': 'generateInspectorProtocolVersion',
           'inputs': [
-            '../inspector/generate-inspector-idl',
+            '../inspector/generate-inspector-protocol-version',
             '../inspector/Inspector.json',
           ],
           'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/webcore/Inspector.idl',
+            '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorProtocolVersion.h',
           ],
           'variables': {
             'generator_include_dirs': [
           },
           'action': [
             'python',
-            '../inspector/generate-inspector-idl',
+            '../inspector/generate-inspector-protocol-version',
             '-o',
             '<@(_outputs)',
             '<@(_inputs)'
           ],
-          'message': 'Generating Inspector protocol sources from Inspector.idl',
+          'message': 'Validate inspector protocol for backwards compatibility and generate version file',
         }
       ]
     },
-    {
-      'target_name': 'inspector_protocol_sources',
-      'type': 'none',
-      'dependencies': [
-        'inspector_idl',
-        'generate_inspector_protocol_version'
-      ],
-      'actions': [
-        {
-          'action_name': 'generateInspectorProtocolSources',
-          # The second input item will be used as item name in vcproj.
-          # It is not possible to put Inspector.idl there because
-          # all idl files are marking as excluded by gyp generator.
-          'inputs': [
-            '../bindings/scripts/generate-bindings.pl',
-            '../inspector/CodeGeneratorInspector.pm',
-            '../bindings/scripts/CodeGenerator.pm',
-            '../bindings/scripts/IDLParser.pm',
-            '../bindings/scripts/IDLStructure.pm',
-            '<(SHARED_INTERMEDIATE_DIR)/webcore/Inspector.idl',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendDispatcher.cpp',
-            '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorBackendStub.js',
-            '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorBackendDispatcher.h',
-            '<(SHARED_INTERMEDIATE_DIR)/webcore/InspectorFrontend.cpp',
-            '<(SHARED_INTERMEDIATE_DIR)/webkit/InspectorFrontend.h',
-          ],
-          'variables': {
-            'generator_include_dirs': [
-            ],
-          },
-          'action': [
-            'python',
-            'scripts/rule_binding.py',
-            '<(SHARED_INTERMEDIATE_DIR)/webcore/Inspector.idl',
-            '<(SHARED_INTERMEDIATE_DIR)/webcore',
-            '<(SHARED_INTERMEDIATE_DIR)/webkit',
-            '--',
-            '<@(_inputs)',
-            '--',
-            '--defines', '<(feature_defines) LANGUAGE_JAVASCRIPT',
-            '--generator', 'Inspector',
-            '<@(generator_include_dirs)'
-          ],
-          'message': 'Generating Inspector protocol sources from Inspector.idl',
-        },
-      ]
-    },
     {
       'target_name': 'injected_script_source',
       'type': 'none',
diff --git a/Source/WebCore/inspector/CodeGeneratorInspector.pm b/Source/WebCore/inspector/CodeGeneratorInspector.pm
deleted file mode 100644 (file)
index 72e2183..0000000
+++ /dev/null
@@ -1,1235 +0,0 @@
-# Copyright (c) 2010 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-package CodeGeneratorInspector;
-
-use strict;
-
-use Class::Struct;
-use File::stat;
-
-my %typeTransform;
-$typeTransform{"ApplicationCache"} = {
-    "forward" => "InspectorApplicationCacheAgent",
-    "header" => "InspectorApplicationCacheAgent.h",
-    "domainAccessor" => "m_applicationCacheAgent",
-};
-$typeTransform{"CSS"} = {
-    "forward" => "InspectorCSSAgent",
-    "header" => "InspectorCSSAgent.h",
-    "domainAccessor" => "m_cssAgent",
-};
-$typeTransform{"Console"} = {
-    "forward" => "InspectorConsoleAgent",
-    "header" => "InspectorConsoleAgent.h",
-    "domainAccessor" => "m_consoleAgent",
-};
-$typeTransform{"Page"} = {
-    "forward" => "InspectorPageAgent",
-    "header" => "InspectorPageAgent.h",
-    "domainAccessor" => "m_pageAgent",
-};
-$typeTransform{"Debugger"} = {
-    "forward" => "InspectorDebuggerAgent",
-    "header" => "InspectorDebuggerAgent.h",
-    "domainAccessor" => "m_debuggerAgent",
-};
-$typeTransform{"DOMDebugger"} = {
-    "forward" => "InspectorDOMDebuggerAgent",
-    "header" => "InspectorDOMDebuggerAgent.h",
-    "domainAccessor" => "m_domDebuggerAgent",
-};
-$typeTransform{"Database"} = {
-    "forward" => "InspectorDatabaseAgent",
-    "header" => "InspectorDatabaseAgent.h",
-    "domainAccessor" => "m_databaseAgent",
-};
-$typeTransform{"DOM"} = {
-    "forward" => "InspectorDOMAgent",
-    "header" => "InspectorDOMAgent.h",
-    "domainAccessor" => "m_domAgent",
-};
-$typeTransform{"DOMStorage"} = {
-    "forward" => "InspectorDOMStorageAgent",
-    "header" => "InspectorDOMStorageAgent.h",
-    "domainAccessor" => "m_domStorageAgent",
-};
-$typeTransform{"FileSystem"} = {
-    "forward" => "InspectorFileSystemAgent",
-    "header" => "InspectorFileSystemAgent.h",
-    "domainAccessor" => "m_fileSystemAgent",
-};
-$typeTransform{"Inspector"} = {
-    "forward" => "InspectorAgent",
-    "header" => "InspectorAgent.h",
-    "domainAccessor" => "m_inspectorAgent",
-};
-$typeTransform{"Network"} = {
-    "forward" => "InspectorResourceAgent",
-    "header" => "InspectorResourceAgent.h",
-    "domainAccessor" => "m_resourceAgent",
-};
-$typeTransform{"Profiler"} = {
-    "forward" => "InspectorProfilerAgent",
-    "header" => "InspectorProfilerAgent.h",
-    "domainAccessor" => "m_profilerAgent",
-};
-$typeTransform{"Runtime"} = {
-    "forward" => "InspectorRuntimeAgent",
-    "header" => "InspectorRuntimeAgent.h",
-    "domainAccessor" => "m_runtimeAgent",
-};
-$typeTransform{"Timeline"} = {
-    "forward" => "InspectorTimelineAgent",
-    "header" => "InspectorTimelineAgent.h",
-    "domainAccessor" => "m_timelineAgent",
-};
-$typeTransform{"Worker"} = {
-    "forward" => "InspectorWorkerAgent",
-    "header" => "InspectorWorkerAgent.h",
-    "domainAccessor" => "m_workerAgent",
-};
-
-$typeTransform{"Frontend"} = {
-    "forward" => "InspectorFrontend",
-    "header" => "InspectorFrontend.h",
-};
-$typeTransform{"PassRefPtr"} = {
-    "forwardHeader" => "wtf/PassRefPtr.h",
-};
-$typeTransform{"RefCounted"} = {
-    "forwardHeader" => "wtf/RefCounted.h",
-};
-$typeTransform{"InspectorFrontendChannel"} = {
-    "forward" => "InspectorFrontendChannel",
-    "header" => "InspectorFrontendChannel.h",
-};
-$typeTransform{"Object"} = {
-    "param" => "PassRefPtr<InspectorObject>",
-    "variable" => "RefPtr<InspectorObject>",
-    "defaultValue" => "InspectorObject::create()",
-    "forward" => "InspectorObject",
-    "header" => "InspectorValues.h",
-    "JSONType" => "Object",
-    "JSType" => "object",
-};
-$typeTransform{"Array"} = {
-    "param" => "PassRefPtr<InspectorArray>",
-    "variable" => "RefPtr<InspectorArray>",
-    "defaultValue" => "InspectorArray::create()",
-    "forward" => "InspectorArray",
-    "header" => "InspectorValues.h",
-    "JSONType" => "Array",
-    "JSType" => "object",
-};
-$typeTransform{"Value"} = {
-    "param" => "PassRefPtr<InspectorValue>",
-    "variable" => "RefPtr<InspectorValue>",
-    "defaultValue" => "InspectorValue::null()",
-    "forward" => "InspectorValue",
-    "header" => "InspectorValues.h",
-    "JSONType" => "Value",
-    "JSType" => "",
-};
-$typeTransform{"String"} = {
-    "param" => "const String&",
-    "optional_param" => "const String* const",
-    "optional_valueAccessor" => "*",
-    "variable" => "String",
-    "return" => "String",
-    "defaultValue" => "\"\"",
-    "forwardHeader" => "PlatformString.h",
-    "header" => "PlatformString.h",
-    "JSONType" => "String",
-    "JSType" => "string"
-};
-$typeTransform{"long"} = {
-    "param" => "long",
-    "optional_param" => "const long* const",
-    "optional_valueAccessor" => "*",
-    "variable" => "long",
-    "defaultValue" => "0",
-    "forward" => "",
-    "header" => "",
-    "JSONType" => "Number",
-    "JSType" => "number"
-};
-$typeTransform{"int"} = {
-    "param" => "int",
-    "optional_param" => "const int* const",
-    "optional_valueAccessor" => "*",
-    "variable" => "int",
-    "defaultValue" => "0",
-    "forward" => "",
-    "header" => "",
-    "JSONType" => "Number",
-    "JSType" => "number"
-};
-$typeTransform{"unsigned long"} = {
-    "param" => "unsigned long",
-    "optional_param" => "const unsigned long* const",
-    "optional_valueAccessor" => "*",
-    "variable" => "unsigned long",
-    "defaultValue" => "0u",
-    "forward" => "",
-    "header" => "",
-    "JSONType" => "Number",
-    "JSType" => "number"
-};
-$typeTransform{"unsigned int"} = {
-    "param" => "unsigned int",
-    "optional_param" => "const unsigned int* const",
-    "optional_valueAccessor" => "*",
-    "variable" => "unsigned int",
-    "defaultValue" => "0u",
-    "forward" => "",
-    "header" => "",
-    "JSONType" => "Number",
-    "JSType" => "number"
-};
-$typeTransform{"double"} = {
-    "param" => "double",
-    "optional_param" => "const double* const",
-    "optional_valueAccessor" => "*",
-    "variable" => "double",
-    "defaultValue" => "0.0",
-    "forward" => "",
-    "header" => "",
-    "JSONType" => "Number",
-    "JSType" => "number"
-};
-$typeTransform{"boolean"} = {
-    "param" => "bool",
-    "optional_param" => "const bool* const",
-    "optional_valueAccessor" => "*",
-    "variable"=> "bool",
-    "defaultValue" => "false",
-    "forward" => "",
-    "header" => "",
-    "JSONType" => "Boolean",
-    "JSType" => "boolean"
-};
-$typeTransform{"void"} = {
-    "forward" => "",
-    "header" => ""
-};
-$typeTransform{"Vector"} = {
-    "header" => "wtf/Vector.h"
-};
-
-# Default License Templates
-
-my $licenseTemplate = << "EOF";
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-EOF
-
-my $codeGenerator;
-my $outputDir;
-my $outputHeadersDir;
-my $writeDependencies;
-my $verbose;
-
-my $namespace;
-
-my $backendClassName;
-my $backendClassDeclaration;
-my $backendJSStubName;
-my %backendTypes;
-my @backendMethods;
-my @backendMethodsImpl;
-my %backendMethodSignatures;
-my $backendConstructor;
-my @backendConstantDeclarations;
-my @backendConstantDefinitions;
-my @backendFooter;
-my @backendJSStubs;
-my @backendJSEvents;
-my %backendDomains;
-
-my $frontendClassName;
-my %frontendTypes;
-my @frontendMethods;
-my @frontendAgentFields;
-my @frontendMethodsImpl;
-my %frontendMethodSignatures;
-my $frontendConstructor;
-my @frontendConstantDeclarations;
-my @frontendConstantDefinitions;
-my @frontendFooter;
-my @frontendDomains;
-
-# Default constructor
-sub new
-{
-    my $object = shift;
-    my $reference = { };
-
-    $codeGenerator = shift;
-    $outputDir = shift;
-    $outputHeadersDir = shift;
-    shift; # $useLayerOnTop
-    shift; # $preprocessor
-    $writeDependencies = shift;
-    $verbose = shift;
-
-    bless($reference, $object);
-    return $reference;
-}
-
-# Params: 'idlDocument' struct
-sub GenerateModule
-{
-    my $object = shift;
-    my $dataNode = shift;
-
-    $namespace = $dataNode->module;
-    $namespace =~ s/core/WebCore/;
-
-    $frontendClassName = "InspectorFrontend";
-    $frontendConstructor = "    ${frontendClassName}(InspectorFrontendChannel*);";
-    push(@frontendFooter, "private:");
-    push(@frontendFooter, "    InspectorFrontendChannel* m_inspectorFrontendChannel;");
-    $frontendTypes{"String"} = 1;
-    $frontendTypes{"InspectorFrontendChannel"} = 1;
-    $frontendTypes{"PassRefPtr"} = 1;
-
-    $backendClassName = "InspectorBackendDispatcher";
-    $backendClassDeclaration = "InspectorBackendDispatcher: public RefCounted<InspectorBackendDispatcher>";
-    $backendJSStubName = "InspectorBackendStub";
-    $backendTypes{"Inspector"} = 1;
-    $backendTypes{"InspectorFrontendChannel"} = 1;
-    $backendTypes{"PassRefPtr"} = 1;
-    $backendTypes{"RefCounted"} = 1;
-    $backendTypes{"Object"} = 1;
-}
-
-# Params: 'idlDocument' struct
-sub GenerateInterface
-{
-    my $object = shift;
-    my $interface = shift;
-    my $defines = shift;
-
-    my %agent = (
-        methodDeclarations => [],
-        methodSignatures => {}
-    );
-    generateFunctions($interface, \%agent);
-    if (@{$agent{methodDeclarations}}) {
-        push(@frontendDomains, $interface->name);
-        generateAgentDeclaration($interface, \%agent);
-    }
-}
-
-sub generateAgentDeclaration
-{
-    my $interface = shift;
-    my $agent = shift;
-    my $agentName = $interface->name;
-    push(@frontendMethods, "    class ${agentName} {");
-    push(@frontendMethods, "    public:");
-    push(@frontendMethods, "        ${agentName}(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }");
-    push(@frontendMethods, @{$agent->{methodDeclarations}});
-    push(@frontendMethods, "        void setInspectorFrontendChannel(InspectorFrontendChannel* inspectorFrontendChannel) { m_inspectorFrontendChannel = inspectorFrontendChannel; }");
-    push(@frontendMethods, "        InspectorFrontendChannel* getInspectorFrontendChannel() { return m_inspectorFrontendChannel; }");
-    push(@frontendMethods, "    private:");
-    push(@frontendMethods, "        InspectorFrontendChannel* m_inspectorFrontendChannel;");
-    push(@frontendMethods, "    };");
-    push(@frontendMethods, "");
-
-    my $getterName = lc($agentName);
-    push(@frontendMethods, "    ${agentName}* ${getterName}() { return &m_${getterName}; }");
-    push(@frontendMethods, "");
-
-    push(@frontendFooter, "    ${agentName} m_${getterName};");
-
-    push(@frontendAgentFields, "m_${getterName}");
-}
-
-sub generateFrontendConstructorImpl
-{
-    my @frontendConstructorImpl;
-    push(@frontendConstructorImpl, "${frontendClassName}::${frontendClassName}(InspectorFrontendChannel* inspectorFrontendChannel)");
-    push(@frontendConstructorImpl, "    : m_inspectorFrontendChannel(inspectorFrontendChannel)");
-    foreach my $agentField (@frontendAgentFields) {
-        push(@frontendConstructorImpl, "    , ${agentField}(inspectorFrontendChannel)");
-    }
-    push(@frontendConstructorImpl, "{");
-    push(@frontendConstructorImpl, "}");
-    return @frontendConstructorImpl;
-}
-
-sub generateFunctions
-{
-    my $interface = shift;
-    my $agent = shift;
-
-    foreach my $function (@{$interface->functions}) {
-        if ($function->signature->extendedAttributes->{"event"}) {
-            generateFrontendFunction($interface, $function, $agent);
-        } else {
-            generateBackendFunction($interface, $function);
-        }
-    }
-
-    collectBackendJSStubFunctions($interface);
-    collectBackendJSStubEvents($interface);
-}
-
-sub generateFrontendFunction
-{
-    my $interface = shift;
-    my $function = shift;
-    my $agent = shift;
-
-    my $functionName = $function->signature->name;
-
-    my $domain = $interface->name;
-    my @argsFiltered = grep($_->direction eq "out", @{$function->parameters}); # just keep only out parameters for frontend interface.
-    map($frontendTypes{$_->type} = 1, @argsFiltered); # register required types.
-    my $arguments = join(", ", map(paramTypeTraits($_, "param") . " " . $_->name, @argsFiltered)); # prepare arguments for function signature.
-
-    my $signature = "        void ${functionName}(${arguments});";
-    !$agent->{methodSignatures}->{$signature} || die "Duplicate frontend function was detected for signature '$signature'.";
-    $agent->{methodSignatures}->{$signature} = 1;
-    push(@{$agent->{methodDeclarations}}, $signature);
-
-    my @function;
-    push(@function, "void ${frontendClassName}::${domain}::${functionName}(${arguments})");
-    push(@function, "{");
-    push(@function, "    RefPtr<InspectorObject> ${functionName}Message = InspectorObject::create();");
-    push(@function, "    ${functionName}Message->setString(\"method\", \"$domain.$functionName\");");
-    if (scalar(@argsFiltered)) {
-        push(@function, "    RefPtr<InspectorObject> paramsObject = InspectorObject::create();");
-
-        foreach my $parameter (@argsFiltered) {
-            my $optional = $parameter->extendedAttributes->{"optional"} ? "if (" . $parameter->name . ")\n        " : "";
-            push(@function, "    " . $optional . "paramsObject->set" . paramTypeTraits($parameter, "JSONType") . "(\"" . $parameter->name . "\", " . paramTypeTraits($parameter, "valueAccessor") . $parameter->name . ");");
-        }
-        push(@function, "    ${functionName}Message->setObject(\"params\", paramsObject);");
-    }
-    push(@function, "    if (m_inspectorFrontendChannel)");
-    push(@function, "        m_inspectorFrontendChannel->sendMessageToFrontend(${functionName}Message->toJSONString());");
-    push(@function, "}");
-    push(@function, "");
-    push(@frontendMethodsImpl, @function);
-}
-
-sub camelCase
-{
-    my $value = shift;
-    $value =~ s/\b(\w)/\U$1/g; # make a camel-case name for type name
-    $value =~ s/ //g;
-    return $value;
-}
-
-sub generateBackendFunction
-{
-    my $interface = shift;
-    my $function = shift;
-
-    my $functionName = $function->signature->name;
-    my $fullQualifiedFunctionName = $interface->name . "_" . $functionName;
-    my $fullQualifiedFunctionNameDot = $interface->name . "." . $functionName;
-
-    push(@backendConstantDeclarations, "        k${fullQualifiedFunctionName}Cmd,");
-    push(@backendConstantDefinitions, "    \"${fullQualifiedFunctionNameDot}\",");
-
-    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 ${fullQualifiedFunctionName}(long callId, InspectorObject* requestMessageObject);";
-    !$backendMethodSignatures{${signature}} || die "Duplicate function was detected for signature '$signature'.";
-    $backendMethodSignatures{${signature}} = "$fullQualifiedFunctionName";
-    push(@backendMethods, ${signature});
-
-    my @function;
-    my $requestMessageObject = scalar(@inArgs) ? " requestMessageObject" : "";
-    push(@function, "void ${backendClassName}::${fullQualifiedFunctionName}(long callId, InspectorObject*$requestMessageObject)");
-    push(@function, "{");
-    push(@function, "    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();");
-    push(@function, "");
-
-    my $domain = $interface->name;
-    my $domainAccessor = typeTraits($domain, "domainAccessor");
-    $backendTypes{$domain} = 1;
-    $backendDomains{$domain} = 1;
-    push(@function, "    if (!$domainAccessor)");
-    push(@function, "        protocolErrors->pushString(\"$domain handler is not available.\");");
-    push(@function, "");
-
-    # declare local variables for out arguments.
-    if (scalar(@outArgs)) {
-        push(@function, map("    " . typeTraits($_->type, "variable") . " out_" . $_->name . " = " . typeTraits($_->type, "defaultValue") . ";", @outArgs));
-        push(@function, "");
-    }
-    push(@function, "    ErrorString error;");
-    push(@function, "");
-
-    my $indent = "";
-    if (scalar(@inArgs)) {
-        push(@function, "    RefPtr<InspectorObject> paramsContainer = requestMessageObject->getObject(\"params\");");
-        push(@function, "    InspectorObject* paramsContainerPtr = paramsContainer.get();");
-        push(@function, "    InspectorArray* protocolErrorsPtr = protocolErrors.get();");
-
-        foreach my $parameter (@inArgs) {
-            my $name = $parameter->name;
-            my $type = $parameter->type;
-            my $typeString = camelCase($parameter->type);
-            my $optionalFlagArgument = "0";
-            if ($parameter->extendedAttributes->{"optional"}) {
-                push(@function, "    bool ${name}_valueFound = false;");
-                $optionalFlagArgument = "&${name}_valueFound";
-            }
-            push(@function, "    " . typeTraits($type, "variable") . " in_$name = get$typeString(paramsContainerPtr, \"$name\", $optionalFlagArgument, protocolErrorsPtr);");
-        }
-        push(@function, "");
-        $indent = "    ";
-    }
-
-    my $args = join(", ",
-                    ("&error",
-                     map(($_->extendedAttributes->{"optional"} ?
-                          $_->name . "_valueFound ? &in_" . $_->name . " : 0" :
-                          "in_" . $_->name), @inArgs),
-                     map("&out_" . $_->name, @outArgs)));
-
-    push(@function, $indent . "if (!protocolErrors->length())");
-    push(@function, $indent . "    $domainAccessor->$functionName($args);");
-    push(@function, "");
-    push(@function, "    RefPtr<InspectorObject> result = InspectorObject::create();");
-    if (scalar(@outArgs)) {
-        push(@function, "    if (!protocolErrors->length() && !error.length()) {");
-        foreach my $parameter (@outArgs) {
-            my $offset = "        ";
-            # Don't add optional boolean parameter to the result unless it is "true"
-            if ($parameter->extendedAttributes->{"optional"} && $parameter->type eq "boolean") {
-                push(@function, $offset . "if (out_" . $parameter->name . ")");
-                $offset .= "    ";
-            }
-            push(@function, $offset . "result->set" . typeTraits($parameter->type, "JSONType") . "(\"" . $parameter->name . "\", out_" . $parameter->name . ");");
-        }
-        push(@function, "    }");
-    }
-    push(@function, "    sendResponse(callId, result, String::format(\"Some arguments of method '%s' can't be processed\", \"$fullQualifiedFunctionNameDot\"), protocolErrors, error);");
-    push(@function, "}");
-    push(@function, "");
-    push(@backendMethodsImpl, @function);
-}
-
-sub generateBackendSendResponse
-{
-    my $sendResponse = << "EOF";
-
-void ${backendClassName}::sendResponse(long callId, PassRefPtr<InspectorObject> result, const String& errorMessage, PassRefPtr<InspectorArray> protocolErrors, ErrorString invocationError)
-{
-    if (protocolErrors->length()) {
-        reportProtocolError(&callId, InvalidParams, errorMessage, protocolErrors);
-        return;
-    }
-    if (invocationError.length()) {
-        reportProtocolError(&callId, ServerError, invocationError);
-        return;
-    }
-
-    RefPtr<InspectorObject> responseMessage = InspectorObject::create();
-    responseMessage->setObject("result", result);
-    responseMessage->setNumber("id", callId);
-    if (m_inspectorFrontendChannel)
-        m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
-}    
-EOF
-    return split("\n", $sendResponse);
-}
-
-sub generateBackendReportProtocolError
-{
-    my $reportProtocolError = << "EOF";
-
-void ${backendClassName}::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const
-{
-    reportProtocolError(callId, code, errorMessage, 0);
-}
-
-void ${backendClassName}::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage, PassRefPtr<InspectorArray> data) const
-{
-    DEFINE_STATIC_LOCAL(Vector<int>,s_commonErrors,);
-    if (!s_commonErrors.size()) {
-        s_commonErrors.insert(ParseError, -32700);
-        s_commonErrors.insert(InvalidRequest, -32600);
-        s_commonErrors.insert(MethodNotFound, -32601);
-        s_commonErrors.insert(InvalidParams, -32602);
-        s_commonErrors.insert(InternalError, -32603);
-        s_commonErrors.insert(ServerError, -32000);
-    }
-    ASSERT(code >=0);
-    ASSERT((unsigned)code < s_commonErrors.size());
-    ASSERT(s_commonErrors[code]);
-    RefPtr<InspectorObject> error = InspectorObject::create();
-    error->setNumber("code", s_commonErrors[code]);
-    error->setString("message", errorMessage);
-    ASSERT(error);
-    if (data)
-        error->setArray("data", data);
-    RefPtr<InspectorObject> message = InspectorObject::create();
-    message->setObject("error", error);
-    if (callId)
-        message->setNumber("id", *callId);
-    else
-        message->setValue("id", InspectorValue::null());
-    if (m_inspectorFrontendChannel)
-        m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
-}
-EOF
-    return split("\n", $reportProtocolError);
-}
-
-sub generateArgumentGetters
-{
-    my $type = shift;
-    my $json = typeTraits($type, "JSONType");
-    my $variable = typeTraits($type, "variable");
-    my $defaultValue = typeTraits($type, "defaultValue");
-    my $return  = typeTraits($type, "return") ? typeTraits($type, "return") : typeTraits($type, "param");
-
-    my $typeString = camelCase($type);
-    push(@backendConstantDeclarations, "    static $return get$typeString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);");
-    my $getterBody = << "EOF";
-
-$return InspectorBackendDispatcher::get$typeString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
-{
-    ASSERT(protocolErrors);
-
-    if (valueFound)
-        *valueFound = false;
-
-    $variable value = $defaultValue;
-
-    if (!object) {
-        if (!valueFound) {
-            // Required parameter in missing params container.
-            protocolErrors->pushString(String::format("'params' object must contain required parameter '\%s' with type '$json'.", name.utf8().data()));
-        }
-        return value;
-    }
-
-    InspectorObject::const_iterator end = object->end();
-    InspectorObject::const_iterator valueIterator = object->find(name);
-
-    if (valueIterator == end) {
-        if (!valueFound)
-            protocolErrors->pushString(String::format("Parameter '\%s' with type '$json' was not found.", name.utf8().data()));
-        return value;
-    }
-
-    if (!valueIterator->second->as$json(&value))
-        protocolErrors->pushString(String::format("Parameter '\%s' has wrong type. It must be '$json'.", name.utf8().data()));
-    else
-        if (valueFound)
-            *valueFound = true;
-    return value;
-}
-EOF
-
-    return split("\n", $getterBody);
-}
-
-sub generateBackendDispatcher
-{
-    my @body;
-    my @mapEntries = map("        &${backendClassName}::$_,", map ($backendMethodSignatures{$_}, @backendMethods));
-    my $mapEntries = join("\n", @mapEntries);
-
-    my $backendDispatcherBody = << "EOF";
-void ${backendClassName}::dispatch(const String& message)
-{
-    RefPtr<${backendClassName}> protect = this;
-    typedef void (${backendClassName}::*CallHandler)(long callId, InspectorObject* messageObject);
-    typedef HashMap<String, CallHandler> DispatchMap;
-    DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
-    long callId = 0;
-
-    if (dispatchMap.isEmpty()) {
-        static CallHandler handlers[] = {
-$mapEntries
-        };
-        size_t length = sizeof(commandNames) / sizeof(commandNames[0]);
-        for (size_t i = 0; i < length; ++i)
-            dispatchMap.add(commandNames[i], handlers[i]);
-    }
-
-    RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
-    if (!parsedMessage) {
-        reportProtocolError(0, ParseError, "Message must be in JSON format");
-        return;
-    }
-
-    RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
-    if (!messageObject) {
-        reportProtocolError(0, InvalidRequest, "Message must be a JSONified object");
-        return;
-    }
-
-    RefPtr<InspectorValue> callIdValue = messageObject->get("id");
-    if (!callIdValue) {
-        reportProtocolError(0, InvalidRequest, "'id' property was not found");
-        return;
-    }
-
-    if (!callIdValue->asNumber(&callId)) {
-        reportProtocolError(0, InvalidRequest, "The type of 'id' property must be number");
-        return;
-    }
-
-    RefPtr<InspectorValue> methodValue = messageObject->get("method");
-    if (!methodValue) {
-        reportProtocolError(&callId, InvalidRequest, "'method' property wasn't found");
-        return;
-    }
-
-    String method;
-    if (!methodValue->asString(&method)) {
-        reportProtocolError(&callId, InvalidRequest, "The type of 'method' property must be string");
-        return;
-    }
-
-    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
-    if (it == dispatchMap.end()) {
-        reportProtocolError(&callId, MethodNotFound, "'" + method + "' wasn't found");
-        return;
-    }
-
-    ((*this).*it->second)(callId, messageObject.get());
-}
-EOF
-    return split("\n", $backendDispatcherBody);
-}
-
-sub generateBackendMessageParser
-{
-    my $messageParserBody = << "EOF";
-bool ${backendClassName}::getCommandName(const String& message, String* result)
-{
-    RefPtr<InspectorValue> value = InspectorValue::parseJSON(message);
-    if (!value)
-        return false;
-
-    RefPtr<InspectorObject> object = value->asObject();
-    if (!object)
-        return false;
-
-    if (!object->getString("method", result))
-        return false;
-
-    return true;
-}
-EOF
-    return split("\n", $messageParserBody);
-}
-
-sub collectBackendJSStubFunctions
-{
-    my $interface = shift;
-    my @functions = grep(!$_->signature->extendedAttributes->{"event"}, @{$interface->functions});
-    my $domain = $interface->name;
-
-    foreach my $function (@functions) {
-        my $name = $function->signature->name;
-        my @inArgs = grep($_->direction eq "in", @{$function->parameters});
-        my $argumentNames = join(
-            ",",
-            map("\"" . $_->name . "\": {"
-                . "\"optional\": " . ($_->extendedAttributes->{"optional"} ? "true " : "false") . ", "
-                . "\"type\": \"" . typeTraits($_->type, "JSType") . "\""
-                . "}",
-                 @inArgs));
-        push(@backendJSStubs, "    this._registerDelegate('{" .
-            "\"method\": \"$domain.$name\", " .
-            (scalar(@inArgs) ? "\"params\": {$argumentNames}, " : "") .
-            "\"id\": 0" .
-        "}');");
-    }
-}
-
-sub collectBackendJSStubEvents
-{
-    my $interface = shift;
-    my @functions = grep($_->signature->extendedAttributes->{"event"}, @{$interface->functions});
-    my $domain = $interface->name;
-
-    foreach my $function (@functions) {
-        my $name = $domain . "." . $function->signature->name;
-        my @outArgs = grep($_->direction eq "out", @{$function->parameters});
-        my $argumentNames = join(",", map("\"" . $_->name . "\"" , @outArgs));
-        push(@backendJSEvents, "    this._eventArgs[\"" . $name . "\"] = [" . $argumentNames ."];");
-    }
-}
-
-sub generateBackendStubJS
-{
-    my $JSRegisterDomainDispatchers = join("\n", map("    this.register" . $_ . "Dispatcher = this._registerDomainDispatcher.bind(this, \"" . $_ ."\");", @frontendDomains));
-    my $JSStubs = join("\n", @backendJSStubs);
-    my $JSEvents = join("\n", @backendJSEvents);
-    my $inspectorBackendStubJS = << "EOF";
-$licenseTemplate
-
-InspectorBackendStub = function()
-{
-    this._lastCallbackId = 1;
-    this._pendingResponsesCount = 0;
-    this._callbacks = {};
-    this._domainDispatchers = {};
-    this._eventArgs = {};
-$JSStubs
-$JSEvents
-$JSRegisterDomainDispatchers
-}
-
-InspectorBackendStub.prototype = {
-    dumpInspectorTimeStats: 0,
-    dumpInspectorProtocolMessages: 0,
-
-    _wrap: function(callback)
-    {
-        var callbackId = this._lastCallbackId++;
-        this._callbacks[callbackId] = callback || function() {};
-        return callbackId;
-    },
-
-    _registerDelegate: function(requestString)
-    {
-        var domainAndFunction = JSON.parse(requestString).method.split(".");
-        var agentName = domainAndFunction[0] + "Agent";
-        if (!window[agentName])
-            window[agentName] = {};
-        window[agentName][domainAndFunction[1]] = this._sendMessageToBackend.bind(this, requestString);
-        window[agentName][domainAndFunction[1]]["invoke"] = this._invoke.bind(this, requestString)
-    },
-
-    _invoke: function(requestString, args, callback)
-    {
-        var request = JSON.parse(requestString);
-        request.params = args;
-        this._wrapCallbackAndSendMessageObject(request, callback);
-    },
-
-    _sendMessageToBackend: function()
-    {
-        var args = Array.prototype.slice.call(arguments);
-        var request = JSON.parse(args.shift());
-        var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : 0;
-        var domainAndMethod = request.method.split(".");
-        var agentMethod = domainAndMethod[0] + "Agent." + domainAndMethod[1];
-
-        var hasParams = false;
-        if (request.params) {
-            for (var key in request.params) {
-                var typeName = request.params[key].type;
-                var optionalFlag = request.params[key].optional;
-
-                if (args.length === 0 && !optionalFlag) {
-                    console.error("Protocol Error: Invalid number of arguments for method '" + agentMethod + "' call. It must have the next arguments '" + JSON.stringify(request.params) + "'.");
-                    return;
-                }
-
-                var value = args.shift();
-                if (optionalFlag && typeof value === "undefined") {
-                    delete request.params[key];
-                    continue;
-                }
-
-                if (typeof value !== typeName) {
-                    console.error("Protocol Error: Invalid type of argument '" + key + "' for method '" + agentMethod + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
-                    return;
-                }
-
-                request.params[key] = value;
-                hasParams = true;
-            }
-            if (!hasParams)
-                delete request.params;
-        }
-
-        if (args.length === 1 && !callback) {
-            if (typeof args[0] !== "undefined") {
-                console.error("Protocol Error: Optional callback argument for method '" + agentMethod + "' call must be a function but its type is '" + typeof args[0] + "'.");
-                return;
-            }
-        }
-
-        this._wrapCallbackAndSendMessageObject(request, callback);
-    },
-
-    _wrapCallbackAndSendMessageObject: function(messageObject, callback)
-    {
-        messageObject.id = this._wrap(callback);
-
-        if (this.dumpInspectorTimeStats) {
-            var wrappedCallback = this._callbacks[messageObject.id];
-            wrappedCallback.methodName = messageObject.method;
-            wrappedCallback.sendRequestTime = Date.now();
-        }
-
-        if (this.dumpInspectorProtocolMessages)
-            console.log("frontend: " + JSON.stringify(messageObject));
-
-        ++this._pendingResponsesCount;
-        this.sendMessageObjectToBackend(messageObject);
-    },
-
-    sendMessageObjectToBackend: function(messageObject)
-    {
-        console.timeStamp(messageObject.method);
-        var message = JSON.stringify(messageObject);
-        InspectorFrontendHost.sendMessageToBackend(message);
-    },
-
-    _registerDomainDispatcher: function(domain, dispatcher)
-    {
-        this._domainDispatchers[domain] = dispatcher;
-    },
-
-    dispatch: function(message)
-    {
-        if (this.dumpInspectorProtocolMessages)
-            console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
-
-        var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
-
-        if ("id" in messageObject) { // just a response for some request
-            if (messageObject.error) {
-                messageObject.error.__proto__ = {
-                    getDescription: function()
-                    {
-                        switch(this.code) {
-                            case -32700: return "Parse error";
-                            case -32600: return "Invalid Request";
-                            case -32601: return "Method not found";
-                            case -32602: return "Invalid params";
-                            case -32603: return "Internal error";;
-                            case -32000: return "Server error";
-                        }
-                    },
-
-                    toString: function()
-                    {
-                        var description ="Unknown error code";
-                        return this.getDescription() + "(" + this.code + "): " + this.message + "." + (this.data ? " " + this.data.join(" ") : "");
-                    },
-
-                    getMessage: function()
-                    {
-                        return this.message;
-                    }
-                }
-
-                if (messageObject.error.code !== -32000)
-                    this.reportProtocolError(messageObject);
-            }
-
-            var arguments = [];
-            if (messageObject.result) {
-                for (var key in messageObject.result)
-                    arguments.push(messageObject.result[key]);
-            }
-
-            var callback = this._callbacks[messageObject.id];
-            if (callback) {
-                var processingStartTime;
-                if (this.dumpInspectorTimeStats && callback.methodName)
-                    processingStartTime = Date.now();
-
-                arguments.unshift(messageObject.error);
-                callback.apply(null, arguments);
-                --this._pendingResponsesCount;
-                delete this._callbacks[messageObject.id];
-
-                if (this.dumpInspectorTimeStats && callback.methodName)
-                    console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
-            }
-
-            if (this._scripts && !this._pendingResponsesCount)
-                this.runAfterPendingDispatches();
-
-            return;
-        } else {
-            var method = messageObject.method.split(".");
-            var domainName = method[0];
-            var functionName = method[1];
-            if (!(domainName in this._domainDispatchers)) {
-                console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
-                return;
-            }
-            var dispatcher = this._domainDispatchers[domainName];
-            if (!(functionName in dispatcher)) {
-                console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
-                return;
-            }
-
-            if (!this._eventArgs[messageObject.method]) {
-                console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
-                return;
-            }
-
-            var params = [];
-            if (messageObject.params) {
-                var paramNames = this._eventArgs[messageObject.method];
-                for (var i = 0; i < paramNames.length; ++i)
-                    params.push(messageObject.params[paramNames[i]]);
-            }
-
-            var processingStartTime;
-            if (this.dumpInspectorTimeStats)
-                processingStartTime = Date.now();
-
-            dispatcher[functionName].apply(dispatcher, params);
-
-            if (this.dumpInspectorTimeStats)
-                console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
-        }
-    },
-
-    reportProtocolError: function(messageObject)
-    {
-        console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
-    },
-
-    runAfterPendingDispatches: function(script)
-    {
-        if (!this._scripts)
-            this._scripts = [];
-
-        if (script)
-            this._scripts.push(script);
-
-        if (!this._pendingResponsesCount) {
-            var scripts = this._scripts;
-            this._scripts = []
-            for (var id = 0; id < scripts.length; ++id)
-                 scripts[id].call(this);
-        }
-    }
-}
-
-InspectorBackend = new InspectorBackendStub();
-
-EOF
-    return split("\n", $inspectorBackendStubJS);
-}
-
-sub generateHeader
-{
-    my $className = shift;
-    my $classDeclaration = shift;
-    my $types = shift;
-    my $constructor = shift;
-    my $constants = shift;
-    my $methods = shift;
-    my $footer = shift;
-
-    my $forwardHeaders = join("\n", sort(map("#include <" . typeTraits($_, "forwardHeader") . ">", grep(typeTraits($_, "forwardHeader"), keys %{$types}))));
-    my $forwardDeclarations = join("\n", sort(map("class " . typeTraits($_, "forward") . ";", grep(typeTraits($_, "forward"), keys %{$types}))));
-    my $constantDeclarations = join("\n", @{$constants});
-    my $methodsDeclarations = join("\n", @{$methods});
-
-    my $headerBody = << "EOF";
-// Copyright (c) 2010 The Chromium 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 ${className}_h
-#define ${className}_h
-
-${forwardHeaders}
-
-namespace $namespace {
-
-$forwardDeclarations
-
-typedef String ErrorString;
-
-class $classDeclaration {
-public:
-$constructor
-
-$constantDeclarations
-$methodsDeclarations
-
-$footer
-};
-
-} // namespace $namespace
-#endif // !defined(${className}_h)
-
-EOF
-    return $headerBody;
-}
-
-sub generateSource
-{
-    my $className = shift;
-    my $types = shift;
-    my $constants = shift;
-    my $methods = shift;
-
-    my @sourceContent = split("\r", $licenseTemplate);
-    push(@sourceContent, "\n#include \"config.h\"");
-    push(@sourceContent, "#include \"$className.h\"");
-    push(@sourceContent, "#include <wtf/text/WTFString.h>");
-    push(@sourceContent, "#include <wtf/text/CString.h>");
-    push(@sourceContent, "");
-    push(@sourceContent, "#if ENABLE(INSPECTOR)");
-    push(@sourceContent, "");
-
-    my %headers;
-    foreach my $type (keys %{$types}) {
-        $headers{"#include \"" . typeTraits($type, "header") . "\""} = 1 if !typeTraits($type, "header") eq  "";
-    }
-    push(@sourceContent, sort keys %headers);
-    push(@sourceContent, "");
-    push(@sourceContent, "namespace $namespace {");
-    push(@sourceContent, "");
-    push(@sourceContent, join("\n", @{$constants}));
-    push(@sourceContent, "");
-    push(@sourceContent, @{$methods});
-    push(@sourceContent, "");
-    push(@sourceContent, "} // namespace $namespace");
-    push(@sourceContent, "");
-    push(@sourceContent, "#endif // ENABLE(INSPECTOR)");
-    push(@sourceContent, "");
-    return @sourceContent;
-}
-
-sub typeTraits
-{
-    my $type = shift;
-    my $trait = shift;
-    return $typeTransform{$type}->{$trait};
-}
-
-sub paramTypeTraits
-{
-    my $paramDescription = shift;
-    my $trait = shift;
-    if ($paramDescription->extendedAttributes->{"optional"}) {
-        my $optionalResult = typeTraits($paramDescription->type, "optional_" . $trait);
-        return $optionalResult if defined $optionalResult;
-    }
-    my $result = typeTraits($paramDescription->type, $trait);
-    return defined $result ? $result : "";
-}
-
-sub generateBackendAgentFieldsAndConstructor
-{
-    my @arguments;
-    my @fieldInitializers;
-
-    push(@arguments, "InspectorFrontendChannel* inspectorFrontendChannel");
-    push(@fieldInitializers, "        : m_inspectorFrontendChannel(inspectorFrontendChannel)");
-    push(@backendFooter, "    InspectorFrontendChannel* m_inspectorFrontendChannel;");
-
-    foreach my $domain (sort keys %backendDomains) {
-        # Add agent field declaration to the footer.
-        my $agentClassName = typeTraits($domain, "forward");
-        my $field = typeTraits($domain, "domainAccessor");
-        push(@backendFooter, "    ${agentClassName}* ${field};");
-
-        # Add agent parameter and initializer.
-        my $arg = substr($field, 2);
-        push(@fieldInitializers, "        , ${field}(${arg})");
-        push(@arguments, "${agentClassName}* ${arg}");
-    }
-
-    my $argumentString = join(", ", @arguments);
-
-    my @backendHead;
-    push(@backendHead, "    ${backendClassName}(${argumentString})");
-    push(@backendHead, @fieldInitializers);
-    push(@backendHead, "    { }");
-    push(@backendHead, "");
-    push(@backendHead, "    void clearFrontend() { m_inspectorFrontendChannel = 0; }");
-    push(@backendHead, "");
-    push(@backendHead, "    enum CommonErrorCode {");
-    push(@backendHead, "        ParseError = 0,");
-    push(@backendHead, "        InvalidRequest,");
-    push(@backendHead, "        MethodNotFound,");
-    push(@backendHead, "        InvalidParams,");
-    push(@backendHead, "        InternalError,");
-    push(@backendHead, "        ServerError,");
-    push(@backendHead, "        LastEntry,");
-    push(@backendHead, "    };");
-    push(@backendHead, "");
-    push(@backendHead, "    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const;");
-    push(@backendHead, "    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<InspectorArray> data) const;");
-    push(@backendHead, "    void dispatch(const String& message);");
-    push(@backendHead, "    static bool getCommandName(const String& message, String* result);");
-    push(@backendHead, "");
-    push(@backendHead, "    enum MethodNames {");
-    $backendConstructor = join("\n", @backendHead);
-}
-
-sub finish
-{
-    my $object = shift;
-
-    push(@backendMethodsImpl, generateBackendDispatcher());
-    push(@backendMethodsImpl, generateBackendSendResponse());
-    push(@backendMethodsImpl, generateBackendReportProtocolError());
-    unshift(@frontendMethodsImpl, generateFrontendConstructorImpl(), "");
-
-    open(my $SOURCE, ">$outputDir/$frontendClassName.cpp") || die "Couldn't open file $outputDir/$frontendClassName.cpp";
-    print $SOURCE join("\n", generateSource($frontendClassName, \%frontendTypes, \@frontendConstantDefinitions, \@frontendMethodsImpl));
-    close($SOURCE);
-    undef($SOURCE);
-
-    open(my $HEADER, ">$outputHeadersDir/$frontendClassName.h") || die "Couldn't open file $outputHeadersDir/$frontendClassName.h";
-    print $HEADER generateHeader($frontendClassName, $frontendClassName, \%frontendTypes, $frontendConstructor, \@frontendConstantDeclarations, \@frontendMethods, join("\n", @frontendFooter));
-    close($HEADER);
-    undef($HEADER);
-
-    unshift(@backendConstantDefinitions, "const char* InspectorBackendDispatcher::commandNames[] = {");
-    push(@backendConstantDefinitions, "};");
-    push(@backendConstantDefinitions, "");
-
-    # Make dispatcher methods private on the backend.
-    push(@backendConstantDeclarations, "};");
-    push(@backendConstantDeclarations, "");
-    push(@backendConstantDeclarations, "    static const char* commandNames[];");    
-    push(@backendConstantDeclarations, "");
-    push(@backendConstantDeclarations, "private:");
-
-    foreach my $type (keys %backendTypes) {
-        if (typeTraits($type, "JSONType")) {
-            push(@backendMethodsImpl, generateArgumentGetters($type));
-        }
-    }
-
-    push(@backendConstantDeclarations, "    void sendResponse(long callId, PassRefPtr<InspectorObject> result, const String& errorMessage, PassRefPtr<InspectorArray> protocolErrors, ErrorString invocationError);");
-
-    generateBackendAgentFieldsAndConstructor();
-
-    push(@backendMethodsImpl, generateBackendMessageParser());
-    push(@backendMethodsImpl, "");
-
-    push(@backendConstantDeclarations, "");
-
-    open($SOURCE, ">$outputDir/$backendClassName.cpp") || die "Couldn't open file $outputDir/$backendClassName.cpp";
-    print $SOURCE join("\n", generateSource($backendClassName, \%backendTypes, \@backendConstantDefinitions, \@backendMethodsImpl));
-    close($SOURCE);
-    undef($SOURCE);
-
-    open($HEADER, ">$outputHeadersDir/$backendClassName.h") || die "Couldn't open file $outputHeadersDir/$backendClassName.h";
-    print $HEADER join("\n", generateHeader($backendClassName, $backendClassDeclaration, \%backendTypes, $backendConstructor, \@backendConstantDeclarations, \@backendMethods, join("\n", @backendFooter)));
-    close($HEADER);
-    undef($HEADER);
-
-    open(my $JS_STUB, ">$outputDir/$backendJSStubName.js") || die "Couldn't open file $outputDir/$backendJSStubName.js";
-    print $JS_STUB join("\n", generateBackendStubJS());
-    close($JS_STUB);
-    undef($JS_STUB);
-}
-
-1;
diff --git a/Source/WebCore/inspector/CodeGeneratorInspector.py b/Source/WebCore/inspector/CodeGeneratorInspector.py
new file mode 100644 (file)
index 0000000..41f3b84
--- /dev/null
@@ -0,0 +1,1426 @@
+#!/usr/bin/env python
+# Copyright (c) 2011 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os.path
+import sys
+import string
+import optparse
+from string import join
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+cmdline_parser = optparse.OptionParser()
+cmdline_parser.add_option("--defines")
+cmdline_parser.add_option("--output_h_dir")
+cmdline_parser.add_option("--output_cpp_dir")
+
+try:
+    arg_options, arg_values = cmdline_parser.parse_args()
+    if (len(arg_values) != 1):
+        raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
+    input_json_filename = arg_values[0]
+    output_header_dirname = arg_options.output_h_dir
+    output_cpp_dirname = arg_options.output_cpp_dir
+    if not output_header_dirname:
+        raise Exception("Output .h directory must be specified")
+    if not output_cpp_dirname:
+        raise Exception("Output .cpp directory must be specified")
+except Exception, e:
+    sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % e)
+    sys.stderr.write("Usage: <script> Inspector.json --output_h_dir <output_header_dir> --output_cpp_dir <output_cpp_dir> [--defines <defines string>]\n")
+    exit(1)
+
+
+def parse_defines(str):
+    if not str:
+        return {}
+
+    items = str.split()
+    result = {}
+    for item in items:
+        if item[0] == '"' and item[-1] == '"' and len(item) >= 2:
+            item = item[1:-1]
+        eq_pos = item.find("=")
+        if eq_pos == -1:
+            key = item
+            value = True
+        else:
+            key = item[:eq_pos]
+            value_str = item[eq_pos + 1:]
+            if value_str == "0":
+                value = False
+            elif value_str == "1":
+                value = True
+            else:
+                # Should we support other values?
+                raise Exception("Unrecognized define value: '%s' (key: '%s')" % (value_str, key))
+        result[key] = value
+    return result
+
+defines_map = parse_defines(arg_options.defines)
+
+
+class DomainNameFixes:
+    @classmethod
+    def get_fixed_data(cls, domain_name):
+        if domain_name in cls.agent_type_map:
+            agent_name_res = cls.agent_type_map[domain_name]
+        else:
+            agent_name_res = "Inspector%sAgent" % domain_name
+
+        if domain_name in cls.agent_field_name_map:
+            field_name_res = cls.agent_field_name_map[domain_name]
+        else:
+            field_name_res = domain_name.lower() + "Agent"
+
+        class Res(object):
+            agent_type_name = agent_name_res
+            hidden = domain_name in cls.hidden_domains
+            skip_js_bind = domain_name in cls.skip_js_bind_domains
+            agent_field_name = field_name_res
+
+            @staticmethod
+            def is_disabled(defines):
+                if not domain_name in cls.domain_define_name_map:
+                    # Has not corresponding preprocessor symbol.
+                    return False
+
+                define_name = cls.domain_define_name_map[domain_name]
+
+                if not define_name in defines:
+                    # Disabled when not mentioned
+                    return True
+
+                define_value = defines[define_name]
+                return not bool(define_value)
+
+        return Res
+
+    skip_js_bind_domains = set(["Runtime", "CSS", "DOMDebugger"])
+    hidden_domains = set(["Inspector"])
+    agent_type_map = {"Network": "InspectorResourceAgent"}
+
+    # TODO: get rid of this, generate names instead.
+    agent_field_name_map = {
+        "Page": "pageAgent",
+        "Runtime": "runtimeAgent",
+        "Console": "consoleAgent",
+        "Network":  "resourceAgent",
+        "Database":  "databaseAgent",
+        "DOMStorage":  "domStorageAgent",
+        "ApplicationCache":  "applicationCacheAgent",
+        "DOM":  "domAgent",
+        "CSS":  "cssAgent",
+        "Debugger": "debuggerAgent",
+        "DOMDebugger": "domDebuggerAgent",
+        "Profiler": "profilerAgent",
+        "Worker": "workerAgent",
+    }
+
+    domain_define_name_map = {
+        "Database": "ENABLE_SQL_DATABASE",
+        "Debugger": "ENABLE_JAVASCRIPT_DEBUGGER",
+        "DOMDebugger": "ENABLE_JAVASCRIPT_DEBUGGER",
+        "Profiler": "ENABLE_JAVASCRIPT_DEBUGGER",
+        "Worker": "ENABLE_WORKERS",
+    }
+
+
+class CParamType(object):
+    def __init__(self, type, setter_format="%s"):
+        self.type = type
+        self.setter_format = setter_format
+
+    def get_text(self):
+        return self.type
+
+    def get_setter_format(self):
+        return self.setter_format
+
+
+class RawTypes(object):
+    @staticmethod
+    def get(json_type):
+        if json_type == "boolean":
+            return RawTypes.Bool
+        elif json_type == "string":
+            return RawTypes.String
+        elif json_type == "array":
+            return RawTypes.Array
+        elif json_type == "object":
+            return RawTypes.Object
+        elif json_type == "integer":
+            return RawTypes.Int
+        elif json_type == "number":
+            return RawTypes.Number
+        else:
+            raise Exception("Unknown type: %s" % json_type)
+
+    class BaseType(object):
+        @classmethod
+        def get_c_param_type(cls, param_type, optional):
+            return cls.default_c_param_type
+
+        @staticmethod
+        def is_event_param_check_optional():
+            return False
+
+    class String(BaseType):
+        @classmethod
+        def get_c_param_type(cls, param_type, optional):
+            if param_type == ParamType.EVENT:
+                return cls._ref_c_type
+            else:
+                return cls._plain_c_type
+
+        @staticmethod
+        def get_getter_name():
+            return "String"
+
+        get_setter_name = get_getter_name
+
+        @staticmethod
+        def get_c_initializer():
+            return "\"\""
+
+        @staticmethod
+        def get_js_bind_type():
+            return "string"
+
+        _plain_c_type = CParamType("String")
+        _ref_c_type = CParamType("const String&")
+
+    class Int(BaseType):
+        @staticmethod
+        def get_getter_name():
+            return "Int"
+
+        @staticmethod
+        def get_setter_name():
+            return "Number"
+
+        @staticmethod
+        def get_c_initializer():
+            return "0"
+
+        @staticmethod
+        def get_js_bind_type():
+            return "number"
+
+        default_c_param_type = CParamType("int")
+
+    class Number(BaseType):
+        @staticmethod
+        def get_getter_name():
+            return "Object"
+
+        @staticmethod
+        def get_setter_name():
+            return "Number"
+
+        @staticmethod
+        def get_c_initializer():
+            raise Exception("Unsupported")
+
+        @staticmethod
+        def get_js_bind_type():
+            raise Exception("Unsupported")
+
+        default_c_param_type = CParamType("double")
+
+    class Bool(BaseType):
+        @classmethod
+        def get_c_param_type(cls, param_type, optional):
+            if (param_type == ParamType.EVENT):
+                if optional:
+                    return cls._ref_c_type
+                else:
+                    return cls._plain_c_type
+            else:
+                return cls._plain_c_type
+
+        @staticmethod
+        def get_getter_name():
+            return "Boolean"
+
+        get_setter_name = get_getter_name
+
+        @staticmethod
+        def get_c_initializer():
+            return "false"
+
+        @staticmethod
+        def get_js_bind_type():
+            return "boolean"
+
+        @staticmethod
+        def is_event_param_check_optional():
+            return True
+
+        _plain_c_type = CParamType("bool")
+        _ref_c_type = CParamType("const bool* const", "*%s")
+
+    class Object(BaseType):
+        @classmethod
+        def get_c_param_type(cls, param_type, optional):
+            if param_type == ParamType.EVENT:
+                return cls._ref_c_type
+            else:
+                return cls._plain_c_type
+
+        @staticmethod
+        def get_getter_name():
+            return "Object"
+
+        get_setter_name = get_getter_name
+
+        @staticmethod
+        def get_c_initializer():
+            return "InspectorObject::create()"
+
+        @staticmethod
+        def get_js_bind_type():
+            return "object"
+
+        @staticmethod
+        def is_event_param_check_optional():
+            return True
+
+        _plain_c_type = CParamType("RefPtr<InspectorObject>")
+        _ref_c_type = CParamType("PassRefPtr<InspectorObject>")
+
+    class Array(BaseType):
+        @classmethod
+        def get_c_param_type(cls, param_type, optional):
+            if param_type == ParamType.OUTPUT:
+                return cls._plain_c_type
+            elif param_type == ParamType.INPUT:
+                return cls._plain_c_type
+            else:
+                return cls._ref_c_type
+
+        @staticmethod
+        def get_getter_name():
+            return "Array"
+
+        get_setter_name = get_getter_name
+
+        @staticmethod
+        def get_c_initializer():
+            return "InspectorArray::create()"
+
+        @staticmethod
+        def get_js_bind_type():
+            return "object"
+
+        @staticmethod
+        def is_event_param_check_optional():
+            return True
+
+        _plain_c_type = CParamType("RefPtr<InspectorArray>")
+        _ref_c_type = CParamType("PassRefPtr<InspectorArray>")
+
+
+class ParamType(object):
+    INPUT = "input"
+    OUTPUT = "output"
+    EVENT = "event"
+
+
+class TypeData(object):
+    def __init__(self, json_type, json_domain):
+        self.json_type_ = json_type
+        self.json_domain_ = json_domain
+
+        if "type" in json_type:
+            json_type_name = json_type["type"]
+            raw_type = RawTypes.get(json_type_name)
+        else:
+            raise Exception("Unknown type")
+        self.raw_type_ = raw_type
+
+    def get_raw_type(self):
+        return self.raw_type_
+
+
+class TypeMap:
+    def __init__(self, api):
+        self.map_ = {}
+        for json_domain in api["domains"]:
+            domain_name = json_domain["domain"]
+
+            domain_map = {}
+            self.map_[domain_name] = domain_map
+
+            if "types" in json_domain:
+                for json_type in json_domain["types"]:
+                    type_name = json_type["id"]
+                    type_data = TypeData(json_type, json_domain)
+                    domain_map[type_name] = type_data
+
+    def get(self, domain_name, type_name):
+        return self.map_[domain_name][type_name]
+
+
+def resolve_param_raw_type(json_parameter, scope_domain_name):
+    if "$ref" in json_parameter:
+        json_ref = json_parameter["$ref"]
+        type_data = get_ref_data(json_ref, scope_domain_name)
+        return type_data.get_raw_type()
+    elif "type" in json_parameter:
+        json_type = json_parameter["type"]
+        return RawTypes.get(json_type)
+    else:
+        raise Exception("Unknown type")
+
+
+def get_ref_data(json_ref, scope_domain_name):
+    dot_pos = json_ref.find(".")
+    if dot_pos == -1:
+        domain_name = scope_domain_name
+        type_name = json_ref
+    else:
+        domain_name = json_ref[:dot_pos]
+        type_name = json_ref[dot_pos + 1:]
+
+    return type_map.get(domain_name, type_name)
+
+
+input_file = open(input_json_filename, "r")
+json_string = input_file.read()
+json_api = json.loads(json_string)
+
+
+class Templates:
+    frontend_domain_class = string.Template(
+"""    class $domainClassName {
+    public:
+        $domainClassName(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
+${frontendDomainMethodDeclarations}        void setInspectorFrontendChannel(InspectorFrontendChannel* inspectorFrontendChannel) { m_inspectorFrontendChannel = inspectorFrontendChannel; }
+        InspectorFrontendChannel* getInspectorFrontendChannel() { return m_inspectorFrontendChannel; }
+    private:
+        InspectorFrontendChannel* m_inspectorFrontendChannel;
+    };
+
+    $domainClassName* $domainFieldName() { return &m_$domainFieldName; }
+
+""")
+
+    backend_method = string.Template(
+"""void InspectorBackendDispatcher::${domainName}_$methodName(long callId, InspectorObject*$requestMessageObject)
+{
+    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
+
+    if (!$agentField)
+        protocolErrors->pushString("${domainName} handler is not available.");
+$methodOutCode
+    ErrorString error;
+$methodInCode
+if (!protocolErrors->length())
+    $agentField->$methodName(&error$agentCallParams);
+
+    RefPtr<InspectorObject> result = InspectorObject::create();
+${responseCook}sendResponse(callId, result, String::format("Some arguments of method '%s' can't be processed", "$domainName.$methodName"), protocolErrors, error);
+}
+""")
+
+    frontend_method = string.Template("""void InspectorFrontend::$domainName::$eventName($parameters)
+{
+    RefPtr<InspectorObject> ${eventName}Message = InspectorObject::create();
+    ${eventName}Message->setString("method", "$domainName.$eventName");
+$code    if (m_inspectorFrontendChannel)
+        m_inspectorFrontendChannel->sendMessageToFrontend(${eventName}Message->toJSONString());
+}
+""")
+
+    frontend_h = string.Template("""// Copyright (c) 2010 The Chromium 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 InspectorFrontend_h
+#define InspectorFrontend_h
+
+#include <PlatformString.h>
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class InspectorArray;
+class InspectorFrontendChannel;
+class InspectorObject;
+
+typedef String ErrorString;
+
+class InspectorFrontend {
+public:
+    InspectorFrontend(InspectorFrontendChannel*);
+
+
+$domainClassList
+private:
+    InspectorFrontendChannel* m_inspectorFrontendChannel;
+${fieldDeclarations}};
+
+} // namespace WebCore
+#endif // !defined(InspectorFrontend_h)
+""")
+
+    backend_h = string.Template("""// Copyright (c) 2010 The Chromium 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 InspectorBackendDispatcher_h
+#define InspectorBackendDispatcher_h
+
+#include <PlatformString.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class InspectorAgent;
+class InspectorObject;
+class InspectorArray;
+class InspectorFrontendChannel;
+
+$forwardDeclarations
+
+typedef String ErrorString;
+
+class InspectorBackendDispatcher: public RefCounted<InspectorBackendDispatcher> {
+public:
+    InspectorBackendDispatcher(InspectorFrontendChannel* inspectorFrontendChannel$constructorParams)
+        : m_inspectorFrontendChannel(inspectorFrontendChannel)
+$constructorInit
+    { }
+
+    void clearFrontend() { m_inspectorFrontendChannel = 0; }
+
+    enum CommonErrorCode {
+        ParseError = 0,
+        InvalidRequest,
+        MethodNotFound,
+        InvalidParams,
+        InternalError,
+        ServerError,
+        LastEntry,
+    };
+
+    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage) const;
+    void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<InspectorArray> data) const;
+    void dispatch(const String& message);
+    static bool getCommandName(const String& message, String* result);
+
+    enum MethodNames {
+
+$methodNamesEnumContent
+};
+
+    static const char* commandNames[];
+
+private:
+    static int getInt(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
+    static String getString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
+    static bool getBoolean(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
+    static PassRefPtr<InspectorObject> getObject(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
+    static PassRefPtr<InspectorArray> getArray(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors);
+    void sendResponse(long callId, PassRefPtr<InspectorObject> result, const String& errorMessage, PassRefPtr<InspectorArray> protocolErrors, ErrorString invocationError);
+
+$methodDeclarations
+
+    InspectorFrontendChannel* m_inspectorFrontendChannel;
+$fieldDeclarations
+};
+
+} // namespace WebCore
+#endif // !defined(InspectorBackendDispatcher_h)
+
+
+""")
+
+    backend_cpp = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "config.h"
+#include "InspectorBackendDispatcher.h"
+#include <wtf/text/WTFString.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR)
+
+#include "InspectorAgent.h"
+#include "InspectorValues.h"
+#include "PlatformString.h"
+#include "InspectorFrontendChannel.h"
+$includes
+
+namespace WebCore {
+
+const char* InspectorBackendDispatcher::commandNames[] = {
+$methodNameDeclarations
+};
+
+
+$methods
+void InspectorBackendDispatcher::dispatch(const String& message)
+{
+    RefPtr<InspectorBackendDispatcher> protect = this;
+    typedef void (InspectorBackendDispatcher::*CallHandler)(long callId, InspectorObject* messageObject);
+    typedef HashMap<String, CallHandler> DispatchMap;
+    DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
+    long callId = 0;
+
+    if (dispatchMap.isEmpty()) {
+        static CallHandler handlers[] = {
+$messageHandlers
+        };
+        size_t length = sizeof(commandNames) / sizeof(commandNames[0]);
+        for (size_t i = 0; i < length; ++i)
+            dispatchMap.add(commandNames[i], handlers[i]);
+    }
+
+    RefPtr<InspectorValue> parsedMessage = InspectorValue::parseJSON(message);
+    if (!parsedMessage) {
+        reportProtocolError(0, ParseError, "Message must be in JSON format");
+        return;
+    }
+
+    RefPtr<InspectorObject> messageObject = parsedMessage->asObject();
+    if (!messageObject) {
+        reportProtocolError(0, InvalidRequest, "Message must be a JSONified object");
+        return;
+    }
+
+    RefPtr<InspectorValue> callIdValue = messageObject->get("id");
+    if (!callIdValue) {
+        reportProtocolError(0, InvalidRequest, "'id' property was not found");
+        return;
+    }
+
+    if (!callIdValue->asNumber(&callId)) {
+        reportProtocolError(0, InvalidRequest, "The type of 'id' property must be number");
+        return;
+    }
+
+    RefPtr<InspectorValue> methodValue = messageObject->get("method");
+    if (!methodValue) {
+        reportProtocolError(&callId, InvalidRequest, "'method' property wasn't found");
+        return;
+    }
+
+    String method;
+    if (!methodValue->asString(&method)) {
+        reportProtocolError(&callId, InvalidRequest, "The type of 'method' property must be string");
+        return;
+    }
+
+    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
+    if (it == dispatchMap.end()) {
+        reportProtocolError(&callId, MethodNotFound, "'" + method + "' wasn't found");
+        return;
+    }
+
+    ((*this).*it->second)(callId, messageObject.get());
+}
+
+void InspectorBackendDispatcher::sendResponse(long callId, PassRefPtr<InspectorObject> result, const String& errorMessage, PassRefPtr<InspectorArray> protocolErrors, ErrorString invocationError)
+{
+    if (protocolErrors->length()) {
+        reportProtocolError(&callId, InvalidParams, errorMessage, protocolErrors);
+        return;
+    }
+    if (invocationError.length()) {
+        reportProtocolError(&callId, ServerError, invocationError);
+        return;
+    }
+
+    RefPtr<InspectorObject> responseMessage = InspectorObject::create();
+    responseMessage->setObject("result", result);
+    responseMessage->setNumber("id", callId);
+    if (m_inspectorFrontendChannel)
+        m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
+}
+
+void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const
+{
+    reportProtocolError(callId, code, errorMessage, 0);
+}
+
+void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage, PassRefPtr<InspectorArray> data) const
+{
+    DEFINE_STATIC_LOCAL(Vector<int>,s_commonErrors,);
+    if (!s_commonErrors.size()) {
+        s_commonErrors.insert(ParseError, -32700);
+        s_commonErrors.insert(InvalidRequest, -32600);
+        s_commonErrors.insert(MethodNotFound, -32601);
+        s_commonErrors.insert(InvalidParams, -32602);
+        s_commonErrors.insert(InternalError, -32603);
+        s_commonErrors.insert(ServerError, -32000);
+    }
+    ASSERT(code >=0);
+    ASSERT((unsigned)code < s_commonErrors.size());
+    ASSERT(s_commonErrors[code]);
+    RefPtr<InspectorObject> error = InspectorObject::create();
+    error->setNumber("code", s_commonErrors[code]);
+    error->setString("message", errorMessage);
+    ASSERT(error);
+    if (data)
+        error->setArray("data", data);
+    RefPtr<InspectorObject> message = InspectorObject::create();
+    message->setObject("error", error);
+    if (callId)
+        message->setNumber("id", *callId);
+    else
+        message->setValue("id", InspectorValue::null());
+    if (m_inspectorFrontendChannel)
+        m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
+}
+
+int InspectorBackendDispatcher::getInt(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+{
+    ASSERT(protocolErrors);
+
+    if (valueFound)
+        *valueFound = false;
+
+    int value = 0;
+
+    if (!object) {
+        if (!valueFound) {
+            // Required parameter in missing params container.
+            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Number'.", name.utf8().data()));
+        }
+        return value;
+    }
+
+    InspectorObject::const_iterator end = object->end();
+    InspectorObject::const_iterator valueIterator = object->find(name);
+
+    if (valueIterator == end) {
+        if (!valueFound)
+            protocolErrors->pushString(String::format("Parameter '%s' with type 'Number' was not found.", name.utf8().data()));
+        return value;
+    }
+
+    if (!valueIterator->second->asNumber(&value))
+        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Number'.", name.utf8().data()));
+    else
+        if (valueFound)
+            *valueFound = true;
+    return value;
+}
+
+String InspectorBackendDispatcher::getString(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+{
+    ASSERT(protocolErrors);
+
+    if (valueFound)
+        *valueFound = false;
+
+    String value = "";
+
+    if (!object) {
+        if (!valueFound) {
+            // Required parameter in missing params container.
+            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'String'.", name.utf8().data()));
+        }
+        return value;
+    }
+
+    InspectorObject::const_iterator end = object->end();
+    InspectorObject::const_iterator valueIterator = object->find(name);
+
+    if (valueIterator == end) {
+        if (!valueFound)
+            protocolErrors->pushString(String::format("Parameter '%s' with type 'String' was not found.", name.utf8().data()));
+        return value;
+    }
+
+    if (!valueIterator->second->asString(&value))
+        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'String'.", name.utf8().data()));
+    else
+        if (valueFound)
+            *valueFound = true;
+    return value;
+}
+
+bool InspectorBackendDispatcher::getBoolean(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+{
+    ASSERT(protocolErrors);
+
+    if (valueFound)
+        *valueFound = false;
+
+    bool value = false;
+
+    if (!object) {
+        if (!valueFound) {
+            // Required parameter in missing params container.
+            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Boolean'.", name.utf8().data()));
+        }
+        return value;
+    }
+
+    InspectorObject::const_iterator end = object->end();
+    InspectorObject::const_iterator valueIterator = object->find(name);
+
+    if (valueIterator == end) {
+        if (!valueFound)
+            protocolErrors->pushString(String::format("Parameter '%s' with type 'Boolean' was not found.", name.utf8().data()));
+        return value;
+    }
+
+    if (!valueIterator->second->asBoolean(&value))
+        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Boolean'.", name.utf8().data()));
+    else
+        if (valueFound)
+            *valueFound = true;
+    return value;
+}
+
+PassRefPtr<InspectorObject> InspectorBackendDispatcher::getObject(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+{
+    ASSERT(protocolErrors);
+
+    if (valueFound)
+        *valueFound = false;
+
+    RefPtr<InspectorObject> value = InspectorObject::create();
+
+    if (!object) {
+        if (!valueFound) {
+            // Required parameter in missing params container.
+            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Object'.", name.utf8().data()));
+        }
+        return value;
+    }
+
+    InspectorObject::const_iterator end = object->end();
+    InspectorObject::const_iterator valueIterator = object->find(name);
+
+    if (valueIterator == end) {
+        if (!valueFound)
+            protocolErrors->pushString(String::format("Parameter '%s' with type 'Object' was not found.", name.utf8().data()));
+        return value;
+    }
+
+    if (!valueIterator->second->asObject(&value))
+        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Object'.", name.utf8().data()));
+    else
+        if (valueFound)
+            *valueFound = true;
+    return value;
+}
+
+PassRefPtr<InspectorArray> InspectorBackendDispatcher::getArray(InspectorObject* object, const String& name, bool* valueFound, InspectorArray* protocolErrors)
+{
+    ASSERT(protocolErrors);
+
+    if (valueFound)
+        *valueFound = false;
+
+    RefPtr<InspectorArray> value = InspectorArray::create();
+
+    if (!object) {
+        if (!valueFound) {
+            // Required parameter in missing params container.
+            protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type 'Array'.", name.utf8().data()));
+        }
+        return value;
+    }
+
+    InspectorObject::const_iterator end = object->end();
+    InspectorObject::const_iterator valueIterator = object->find(name);
+
+    if (valueIterator == end) {
+        if (!valueFound)
+            protocolErrors->pushString(String::format("Parameter '%s' with type 'Array' was not found.", name.utf8().data()));
+        return value;
+    }
+
+    if (!valueIterator->second->asArray(&value))
+        protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be 'Array'.", name.utf8().data()));
+    else
+        if (valueFound)
+            *valueFound = true;
+    return value;
+}
+bool InspectorBackendDispatcher::getCommandName(const String& message, String* result)
+{
+    RefPtr<InspectorValue> value = InspectorValue::parseJSON(message);
+    if (!value)
+        return false;
+
+    RefPtr<InspectorObject> object = value->asObject();
+    if (!object)
+        return false;
+
+    if (!object->getString("method", result))
+        return false;
+
+    return true;
+}
+
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
+""")
+
+    frontend_cpp = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "config.h"
+#include "InspectorFrontend.h"
+#include <wtf/text/WTFString.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(INSPECTOR)
+
+#include "InspectorFrontendChannel.h"
+#include "InspectorValues.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+
+
+InspectorFrontend::InspectorFrontend(InspectorFrontendChannel* inspectorFrontendChannel)
+    : m_inspectorFrontendChannel(inspectorFrontendChannel)
+$constructorInit{
+}
+
+$methods
+
+} // namespace WebCore
+
+#endif // ENABLE(INSPECTOR)
+""")
+
+    backend_js = string.Template("""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+InspectorBackendStub = function()
+{
+    this._lastCallbackId = 1;
+    this._pendingResponsesCount = 0;
+    this._callbacks = {};
+    this._domainDispatchers = {};
+    this._eventArgs = {};
+$delegates$eventArgs$domainDispatchers    }
+
+InspectorBackendStub.prototype = {
+    dumpInspectorTimeStats: 0,
+    dumpInspectorProtocolMessages: 0,
+
+    _wrap: function(callback)
+    {
+        var callbackId = this._lastCallbackId++;
+        this._callbacks[callbackId] = callback || function() {};
+        return callbackId;
+    },
+
+    _registerDelegate: function(requestString)
+    {
+        var domainAndFunction = JSON.parse(requestString).method.split(".");
+        var agentName = domainAndFunction[0] + "Agent";
+        if (!window[agentName])
+            window[agentName] = {};
+        window[agentName][domainAndFunction[1]] = this._sendMessageToBackend.bind(this, requestString);
+        window[agentName][domainAndFunction[1]]["invoke"] = this._invoke.bind(this, requestString)
+    },
+
+    _invoke: function(requestString, args, callback)
+    {
+        var request = JSON.parse(requestString);
+        request.params = args;
+        this._wrapCallbackAndSendMessageObject(request, callback);
+    },
+
+    _sendMessageToBackend: function()
+    {
+        var args = Array.prototype.slice.call(arguments);
+        var request = JSON.parse(args.shift());
+        var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : 0;
+        var domainAndMethod = request.method.split(".");
+        var agentMethod = domainAndMethod[0] + "Agent." + domainAndMethod[1];
+
+        var hasParams = false;
+        if (request.params) {
+            for (var key in request.params) {
+                var typeName = request.params[key].type;
+                var optionalFlag = request.params[key].optional;
+
+                if (args.length === 0 && !optionalFlag) {
+                    console.error("Protocol Error: Invalid number of arguments for method '" + agentMethod + "' call. It must have the next arguments '" + JSON.stringify(request.params) + "'.");
+                    return;
+                }
+
+                var value = args.shift();
+                if (optionalFlag && typeof value === "undefined") {
+                    delete request.params[key];
+                    continue;
+                }
+
+                if (typeof value !== typeName) {
+                    console.error("Protocol Error: Invalid type of argument '" + key + "' for method '" + agentMethod + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
+                    return;
+                }
+
+                request.params[key] = value;
+                hasParams = true;
+            }
+            if (!hasParams)
+                delete request.params;
+        }
+
+        if (args.length === 1 && !callback) {
+            if (typeof args[0] !== "undefined") {
+                console.error("Protocol Error: Optional callback argument for method '" + agentMethod + "' call must be a function but its type is '" + typeof args[0] + "'.");
+                return;
+            }
+        }
+
+        this._wrapCallbackAndSendMessageObject(request, callback);
+    },
+
+    _wrapCallbackAndSendMessageObject: function(messageObject, callback)
+    {
+        messageObject.id = this._wrap(callback);
+
+        if (this.dumpInspectorTimeStats) {
+            var wrappedCallback = this._callbacks[messageObject.id];
+            wrappedCallback.methodName = messageObject.method;
+            wrappedCallback.sendRequestTime = Date.now();
+        }
+
+        if (this.dumpInspectorProtocolMessages)
+            console.log("frontend: " + JSON.stringify(messageObject));
+
+        ++this._pendingResponsesCount;
+        this.sendMessageObjectToBackend(messageObject);
+    },
+
+    sendMessageObjectToBackend: function(messageObject)
+    {
+        console.timeStamp(messageObject.method);
+        var message = JSON.stringify(messageObject);
+        InspectorFrontendHost.sendMessageToBackend(message);
+    },
+
+    _registerDomainDispatcher: function(domain, dispatcher)
+    {
+        this._domainDispatchers[domain] = dispatcher;
+    },
+
+    dispatch: function(message)
+    {
+        if (this.dumpInspectorProtocolMessages)
+            console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
+
+        var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
+
+        if ("id" in messageObject) { // just a response for some request
+            if (messageObject.error) {
+                messageObject.error.__proto__ = {
+                    getDescription: function()
+                    {
+                        switch(this.code) {
+                            case -32700: return "Parse error";
+                            case -32600: return "Invalid Request";
+                            case -32601: return "Method not found";
+                            case -32602: return "Invalid params";
+                            case -32603: return "Internal error";;
+                            case -32000: return "Server error";
+                        }
+                    },
+
+                    toString: function()
+                    {
+                        var description ="Unknown error code";
+                        return this.getDescription() + "(" + this.code + "): " + this.message + "." + (this.data ? " " + this.data.join(" ") : "");
+                    },
+
+                    getMessage: function()
+                    {
+                        return this.message;
+                    }
+                }
+
+                if (messageObject.error.code !== -32000)
+                    this.reportProtocolError(messageObject);
+            }
+
+            var arguments = [];
+            if (messageObject.result) {
+                for (var key in messageObject.result)
+                    arguments.push(messageObject.result[key]);
+            }
+
+            var callback = this._callbacks[messageObject.id];
+            if (callback) {
+                var processingStartTime;
+                if (this.dumpInspectorTimeStats && callback.methodName)
+                    processingStartTime = Date.now();
+
+                arguments.unshift(messageObject.error);
+                callback.apply(null, arguments);
+                --this._pendingResponsesCount;
+                delete this._callbacks[messageObject.id];
+
+                if (this.dumpInspectorTimeStats && callback.methodName)
+                    console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
+            }
+
+            if (this._scripts && !this._pendingResponsesCount)
+                this.runAfterPendingDispatches();
+
+            return;
+        } else {
+            var method = messageObject.method.split(".");
+            var domainName = method[0];
+            var functionName = method[1];
+            if (!(domainName in this._domainDispatchers)) {
+                console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
+                return;
+            }
+            var dispatcher = this._domainDispatchers[domainName];
+            if (!(functionName in dispatcher)) {
+                console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
+                return;
+            }
+
+            if (!this._eventArgs[messageObject.method]) {
+                console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
+                return;
+            }
+
+            var params = [];
+            if (messageObject.params) {
+                var paramNames = this._eventArgs[messageObject.method];
+                for (var i = 0; i < paramNames.length; ++i)
+                    params.push(messageObject.params[paramNames[i]]);
+            }
+
+            var processingStartTime;
+            if (this.dumpInspectorTimeStats)
+                processingStartTime = Date.now();
+
+            dispatcher[functionName].apply(dispatcher, params);
+
+            if (this.dumpInspectorTimeStats)
+                console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
+        }
+    },
+
+    reportProtocolError: function(messageObject)
+    {
+        console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
+    },
+
+    runAfterPendingDispatches: function(script)
+    {
+        if (!this._scripts)
+            this._scripts = [];
+
+        if (script)
+            this._scripts.push(script);
+
+        if (!this._pendingResponsesCount) {
+            var scripts = this._scripts;
+            this._scripts = []
+            for (var id = 0; id < scripts.length; ++id)
+                 scripts[id].call(this);
+        }
+    }
+}
+
+InspectorBackend = new InspectorBackendStub();""")
+
+    param_container_access_code = """
+    RefPtr<InspectorObject> paramsContainer = requestMessageObject->getObject("params");
+    InspectorObject* paramsContainerPtr = paramsContainer.get();
+    InspectorArray* protocolErrorsPtr = protocolErrors.get();
+"""
+
+
+type_map = TypeMap(json_api)
+
+
+class Generator:
+    frontend_class_field_lines = []
+    frontend_domain_class_lines = []
+
+    method_name_enum_list = []
+    backend_method_declaration_list = []
+    backend_method_implementation_list = []
+    backend_method_name_declaration_list = []
+    method_handler_list = []
+    frontend_method_list = []
+    backend_js_initializer_list = []
+    backend_js_event_list = []
+    backend_js_domain_dispatcher_list = []
+
+    backend_constructor_param_list = []
+    backend_constructor_init_list = []
+    backend_field_list = []
+    backend_forward_list = []
+    backend_include_list = []
+    frontend_constructor_init_list = []
+
+    @staticmethod
+    def go():
+        for json_domain in json_api["domains"]:
+            domain_name = json_domain["domain"]
+            domain_name_lower = domain_name.lower()
+
+            domain_data = DomainNameFixes.get_fixed_data(domain_name)
+
+            if domain_data.is_disabled(defines_map):
+                continue
+
+            agent_field_name = domain_data.agent_field_name
+
+            frontend_method_declaration_lines = []
+            if "events" in json_domain:
+                for json_event in json_domain["events"]:
+                    Generator.process_event(json_event, domain_name, frontend_method_declaration_lines)
+
+                Generator.frontend_class_field_lines.append("    %s m_%s;\n" % (domain_name, domain_name_lower))
+                Generator.frontend_constructor_init_list.append("    , m_%s(inspectorFrontendChannel)\n" % domain_name_lower)
+                Generator.frontend_domain_class_lines.append(Templates.frontend_domain_class.substitute(None,
+                    domainClassName=domain_name,
+                    domainFieldName=domain_name_lower,
+                    frontendDomainMethodDeclarations=join(frontend_method_declaration_lines, "")))
+            if "commands" in json_domain:
+                for json_command in json_domain["commands"]:
+                    Generator.process_command(json_command, domain_name, agent_field_name)
+
+            if not domain_data.skip_js_bind:
+                Generator.backend_js_domain_dispatcher_list.append("    this.register%sDispatcher = this._registerDomainDispatcher.bind(this, \"%s\");\n" % (domain_name, domain_name))
+
+        sorted_json_domains = list(json_api["domains"])
+        sorted_json_domains.sort(key=lambda o: o["domain"])
+
+        for json_domain in sorted_json_domains:
+            domain_name = json_domain["domain"]
+
+            domain_data = DomainNameFixes.get_fixed_data(domain_name)
+            if domain_data.is_disabled(defines_map):
+                continue
+
+            if domain_data.hidden:
+                continue
+            agent_type_name = domain_data.agent_type_name
+            agent_field_name = domain_data.agent_field_name
+            Generator.backend_constructor_param_list.append(", %s* %s" % (agent_type_name, agent_field_name))
+            Generator.backend_constructor_init_list.append("        , m_%s(%s)" % (agent_field_name, agent_field_name))
+            Generator.backend_field_list.append("    %s* m_%s;" % (agent_type_name, agent_field_name))
+            Generator.backend_forward_list.append("class %s;" % agent_type_name)
+            Generator.backend_include_list.append("#include \"%s.h\"" % agent_type_name)
+
+    @staticmethod
+    def process_event(json_event, domain_name, frontend_method_declaration_lines):
+        event_name = json_event["name"]
+        parameter_list = []
+        method_line_list = []
+        backend_js_event_param_list = []
+        if "parameters" in json_event:
+            method_line_list.append("    RefPtr<InspectorObject> paramsObject = InspectorObject::create();\n")
+            for json_parameter in json_event["parameters"]:
+                parameter_name = json_parameter["name"]
+
+                raw_type = resolve_param_raw_type(json_parameter, domain_name)
+
+                json_optional = "optional" in json_parameter and json_parameter["optional"]
+
+                optional_mask = raw_type.is_event_param_check_optional()
+                c_type = raw_type.get_c_param_type(ParamType.EVENT, json_optional)
+
+                setter_type = raw_type.get_setter_name()
+
+                optional = optional_mask and json_optional
+
+                parameter_list.append("%s %s" % (c_type.get_text(), parameter_name))
+
+                setter_argument = c_type.get_setter_format() % parameter_name
+
+                setter_code = "    paramsObject->set%s(\"%s\", %s);\n" % (setter_type, parameter_name, setter_argument)
+                if optional:
+                    setter_code = ("    if (%s)\n    " % parameter_name) + setter_code
+                method_line_list.append(setter_code)
+
+                backend_js_event_param_list.append("\"%s\"" % parameter_name)
+            method_line_list.append("    %sMessage->setObject(\"params\", paramsObject);\n" % event_name)
+        frontend_method_declaration_lines.append(
+            "        void %s(%s);\n" % (event_name, join(parameter_list, ", ")))
+
+        Generator.frontend_method_list.append(Templates.frontend_method.substitute(None,
+            domainName=domain_name, eventName=event_name,
+            parameters=join(parameter_list, ", "),
+            code=join(method_line_list, "")))
+
+        Generator.backend_js_event_list.append("    this._eventArgs[\"%s.%s\"] = [%s];\n" % (
+            domain_name, event_name, join(backend_js_event_param_list, ", ")))
+
+    @staticmethod
+    def process_command(json_command, domain_name, agent_field_name):
+        json_command_name = json_command["name"]
+        Generator.method_name_enum_list.append("        k%s_%sCmd," % (domain_name, json_command["name"]))
+        Generator.method_handler_list.append("        &InspectorBackendDispatcher::%s_%s," % (domain_name, json_command_name))
+        Generator.backend_method_declaration_list.append("    void %s_%s(long callId, InspectorObject* requestMessageObject);" % (domain_name, json_command_name))
+
+        method_in_code = ""
+        method_out_code = ""
+        agent_call_param_list = []
+        response_cook_list = []
+        request_message_param = ""
+        js_parameters_text = ""
+        if "parameters" in json_command:
+            json_params = json_command["parameters"]
+            method_in_code += Templates.param_container_access_code
+            request_message_param = " requestMessageObject"
+            js_param_list = []
+
+            for json_parameter in json_params:
+                json_param_name = json_parameter["name"]
+                param_raw_type = resolve_param_raw_type(json_parameter, domain_name)
+
+                var_type = param_raw_type.get_c_param_type(ParamType.INPUT, None)
+                getter_name = param_raw_type.get_getter_name()
+
+                if "optional" in json_parameter and json_parameter["optional"]:
+                    code = ("    bool %s_valueFound = false;\n"
+                            "    %s in_%s = get%s(paramsContainerPtr, \"%s\", &%s_valueFound, protocolErrorsPtr);\n" %
+                           (json_param_name, var_type.get_text(), json_param_name, getter_name, json_param_name, json_param_name))
+                    param = ", %s_valueFound ? &in_%s : 0" % (json_param_name, json_param_name)
+                else:
+                    code = ("    %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrorsPtr);\n" %
+                            (var_type.get_text(), json_param_name, getter_name, json_param_name))
+                    param = ", in_%s" % json_param_name
+
+                method_in_code += code
+                agent_call_param_list.append(param)
+
+                js_bind_type = param_raw_type.get_js_bind_type()
+                js_param_text = "\"%s\": {\"optional\": %s, \"type\": \"%s\"}" % (
+                    json_param_name,
+                    ("true" if ("optional" in json_parameter and json_parameter["optional"]) else "false"),
+                    js_bind_type)
+
+                js_param_list.append(js_param_text)
+
+            js_parameters_text = ", \"params\": {" + join(js_param_list, ", ") + "}"
+
+        response_cook_text = ""
+        if "returns" in json_command:
+            method_out_code += "\n"
+            for json_return in json_command["returns"]:
+
+                json_return_name = json_return["name"]
+                raw_type = resolve_param_raw_type(json_return, domain_name)
+                setter_type = raw_type.get_setter_name()
+                initializer = raw_type.get_c_initializer()
+                var_type = raw_type.get_c_param_type(ParamType.OUTPUT, None)
+
+                code = "    %s out_%s = %s;\n" % (var_type.get_text(), json_return_name, initializer)
+                param = ", &out_%s" % json_return_name
+                cook = "        result->set%s(\"%s\", out_%s);\n" % (setter_type, json_return_name, json_return_name)
+                if var_type.get_text() == "bool" and "optional" in json_return and json_return["optional"]:
+                    cook = ("        if (out_%s)\n    " % json_return_name) + cook
+
+                method_out_code += code
+                agent_call_param_list.append(param)
+                response_cook_list.append(cook)
+            response_cook_text = "    if (!protocolErrors->length() && !error.length()) {\n%s    }\n" % join(response_cook_list, "")
+
+        Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
+            domainName=domain_name, methodName=json_command_name,
+            agentField="m_" + agent_field_name,
+            methodInCode=method_in_code,
+            methodOutCode=method_out_code,
+            agentCallParams=join(agent_call_param_list, ""),
+            requestMessageObject=request_message_param,
+            responseCook=response_cook_text))
+        Generator.backend_method_name_declaration_list.append("    \"%s.%s\"," % (domain_name, json_command_name))
+
+        Generator.backend_js_initializer_list.append("        this._registerDelegate('{\"method\": \"%s.%s\"%s, \"id\": 0}');\n" % (domain_name, json_command_name, js_parameters_text))
+
+
+Generator.go()
+
+backend_h_file = open(output_header_dirname + "/InspectorBackendDispatcher.h", "w")
+backend_cpp_file = open(output_cpp_dirname + "/InspectorBackendDispatcher.cpp", "w")
+
+frontend_h_file = open(output_header_dirname + "/InspectorFrontend.h", "w")
+frontend_cpp_file = open(output_cpp_dirname + "/InspectorFrontend.cpp", "w")
+
+backend_js_file = open(output_cpp_dirname + "/InspectorBackendStub.js", "w")
+
+
+frontend_h_file.write(Templates.frontend_h.substitute(None,
+         fieldDeclarations=join(Generator.frontend_class_field_lines, ""),
+         domainClassList=join(Generator.frontend_domain_class_lines, "")))
+
+backend_h_file.write(Templates.backend_h.substitute(None,
+    constructorInit=join(Generator.backend_constructor_init_list, "\n"),
+    constructorParams=join(Generator.backend_constructor_param_list, ""),
+    methodNamesEnumContent=join(Generator.method_name_enum_list, "\n"),
+    methodDeclarations=join(Generator.backend_method_declaration_list, "\n"),
+    fieldDeclarations=join(Generator.backend_field_list, "\n"),
+    forwardDeclarations=join(Generator.backend_forward_list, "\n")))
+
+frontend_cpp_file.write(Templates.frontend_cpp.substitute(None,
+    constructorInit=join(Generator.frontend_constructor_init_list, ""),
+    methods=join(Generator.frontend_method_list, "\n")))
+
+backend_cpp_file.write(Templates.backend_cpp.substitute(None,
+    methodNameDeclarations=join(Generator.backend_method_name_declaration_list, "\n"),
+    includes=join(Generator.backend_include_list, "\n"),
+    methods=join(Generator.backend_method_implementation_list, "\n"),
+    messageHandlers=join(Generator.method_handler_list, "\n")))
+
+backend_js_file.write(Templates.backend_js.substitute(None,
+    delegates=join(Generator.backend_js_initializer_list, ""),
+    eventArgs=join(Generator.backend_js_event_list, ""),
+    domainDispatchers=join(Generator.backend_js_domain_dispatcher_list, "")))
+
+backend_h_file.close()
+backend_cpp_file.close()
+
+frontend_h_file.close()
+frontend_cpp_file.close()
+
+backend_js_file.close()
index 0705f601f85a99168507aa6dc14ed1c5e44131db..c55be40b15bd21ce9c016a589b7b2385f8596f7f 100644 (file)
                     { "name": "session", "type": "boolean", "description": "True in case of session cookie." }
                 ],
                 "hidden": true
-            },
+            }
         ],
         "commands": [
             {
                     { "name": "isLocalStorage", "type": "boolean", "description": "True for local storage." },
                     { "name": "id", "type": "number", "description": "Entry id for further reference." }
                 ]
-            },
+            }
         ],
         "commands": [
             {
diff --git a/Source/WebCore/inspector/generate-inspector-idl b/Source/WebCore/inspector/generate-inspector-idl
deleted file mode 100755 (executable)
index 17ae661..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-# 
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import os.path
-import sys
-
-program_name = os.path.basename(__file__)
-if len(sys.argv) < 4 or sys.argv[1] != "-o":
-    sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE\n" % program_name)
-    exit(1)
-
-output_path = sys.argv[2]
-input_path = sys.argv[3]
-
-input_file = open(input_path, "r")
-json_string = input_file.read()
-json_string = json_string.replace(": true", ": True")
-json_string = json_string.replace(": false", ": false")
-json_api = eval(json_string)["domains"]
-
-output_file = open(output_path, "w")
-output_file.write("""/*
- * Copyright (C) 2011 Google, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-module core {""")
-
-type_traits = {
-    "string": "String",
-    "integer": "int",
-    "number": "double",
-    "boolean": "boolean",
-    "array": "Array",
-    "object": "Object"
-}
-
-ref_types = {}
-
-macro_traits = {
-    "Database": "SQL_DATABASE",
-    "Debugger": "JAVASCRIPT_DEBUGGER",
-    "DOMDebugger": "JAVASCRIPT_DEBUGGER",
-    "Profiler": "JAVASCRIPT_DEBUGGER",
-    "Worker": "WORKERS"
-}
-
-def full_qualified_type_id(domain_name, type_id):
-    if type_id.find(".") == -1:
-       return "%s.%s" % (domain_name, type_id)
-    return type_id
-    
-
-def param_type(domain_name, param):
-    if "type" in param:
-        return type_traits[param["type"]]
-    if "$ref" in param:
-        type_id = full_qualified_type_id(domain_name, param["$ref"])
-        if type_id in ref_types:
-            ref_type = ref_types[type_id]
-            return type_traits[ref_type["type"]]
-        else:
-            print("Type not found: " + type_id)
-            return "!! Type not found: " + type_id
-
-for domain in json_api:
-    domain_name = domain["domain"]
-    if "types" in domain:
-        for type in domain["types"]:
-            type_id = full_qualified_type_id(domain_name, type["id"])
-            ref_types[type_id] = type;
-
-for domain in json_api:
-    domain_name = domain["domain"]
-    if domain_name in macro_traits:
-        output_file.write("\n#if defined(ENABLE_%s) && ENABLE_%s" % (macro_traits[domain_name], macro_traits[domain_name]))
-    output_file.write("\n    interface [Conditional=INSPECTOR] %s {" % domain_name)
-
-    if "commands" in domain:
-        for command in domain["commands"]:
-            params = []
-            if ("parameters" in command):
-                for in_param in command["parameters"]:
-                    if ("optional" in in_param):
-                        optional = " [optional]"
-                    else:
-                        optional = ""
-                    params.append("in%s %s %s" % (optional, param_type(domain_name, in_param), in_param["name"]))
-            if ("returns" in command):
-                for out_param in command["returns"]:
-                    if ("optional" in out_param):
-                        optional = " [optional]"
-                    else:
-                        optional = ""
-                    params.append("out%s %s %s" % (optional, param_type(domain_name, out_param), out_param["name"]))
-            output_file.write("\n        void %s(%s);" % (command["name"], ", ".join(params)))
-
-    if "events" in domain:
-        for event in domain["events"]:
-            params = []
-            if ("parameters" in event):
-                for in_param in event["parameters"]:
-                    if ("optional" in in_param):
-                        optional = " [optional]"
-                    else:
-                        optional = ""
-                    params.append("out%s %s %s" % (optional, param_type(domain_name, in_param), in_param["name"]))
-            output_file.write("\n        [event] void %s(%s);" % (event["name"], ", ".join(params)))
-
-    output_file.write("\n    };")
-    if domain["domain"] in macro_traits:
-        output_file.write("\n#endif // ENABLE_%s" % macro_traits[domain["domain"]])
-output_file.write("\n}\n")
-output_file.close()