Changeset 127603 in webkit


Ignore:
Timestamp:
Sep 5, 2012 9:44:31 AM (12 years ago)
Author:
vsevik@chromium.org
Message:

Web Inspector: CodeGeneratorInspector.py: support asynchronous command implementation
https://bugs.webkit.org/show_bug.cgi?id=95649

Patch by Peter Rybin <peter.rybin@gmail.com> on 2012-09-05
Reviewed by Yury Semikhatsky.

Generator is extended to generate callback object for each asynchronous command.

  • inspector/CodeGeneratorInspector.py:

(Writer.append_multiline):
(Writer):
(Writer.get_indent):
(TypeBindings.create_type_declaration_.ClassBinding.resolve_inner.ResolveData):
(InspectorBackendDispatcherImpl):
(CallbackBase):
(Generator.process_event):
(Generator):
(Generator.EventMethodStructTemplate):
(Generator.EventMethodStructTemplate.append_prolog):
(Generator.EventMethodStructTemplate.append_epilog):
(Generator.process_command):
(Generator.CallbackMethodStructTemplate):
(Generator.CallbackMethodStructTemplate.append_prolog):
(Generator.CallbackMethodStructTemplate.append_epilog):
(Generator.generate_send_method):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r127597 r127603  
     12012-09-05  Peter Rybin  <peter.rybin@gmail.com>
     2
     3        Web Inspector: CodeGeneratorInspector.py: support asynchronous command implementation
     4        https://bugs.webkit.org/show_bug.cgi?id=95649
     5
     6        Reviewed by Yury Semikhatsky.
     7
     8        Generator is extended to generate callback object for each asynchronous command.
     9
     10        * inspector/CodeGeneratorInspector.py:
     11        (Writer.append_multiline):
     12        (Writer):
     13        (Writer.get_indent):
     14        (TypeBindings.create_type_declaration_.ClassBinding.resolve_inner.ResolveData):
     15        (InspectorBackendDispatcherImpl):
     16        (CallbackBase):
     17        (Generator.process_event):
     18        (Generator):
     19        (Generator.EventMethodStructTemplate):
     20        (Generator.EventMethodStructTemplate.append_prolog):
     21        (Generator.EventMethodStructTemplate.append_epilog):
     22        (Generator.process_command):
     23        (Generator.CallbackMethodStructTemplate):
     24        (Generator.CallbackMethodStructTemplate.append_prolog):
     25        (Generator.CallbackMethodStructTemplate.append_epilog):
     26        (Generator.generate_send_method):
     27
    1282012-09-05  Kevin Ellis  <kevers@chromium.org>
    229
  • trunk/Source/WebCore/inspector/CodeGeneratorInspector.py

    r126926 r127603  
    771771                self.newline(p)
    772772
     773    def get_indent(self):
     774        return self.indent
     775
    773776    def get_indented(self, additional_indent):
    774777        return Writer(self.output, self.indent + additional_indent)
     
    11111114                            main_properties = main
    11121115                            optional_properties = optional
    1113                             ad_hoc_types = ad_hoc_type_context.ad_hoc_type_list
     1116                            ad_hoc_types = ad_hoc_type_list
    11141117
    11151118                        cls.resolve_data_ = ResolveData
     
    17841787    frontend_method = string.Template("""void InspectorFrontend::$domainName::$eventName($parameters)
    17851788{
    1786     RefPtr<InspectorObject> ${eventName}Message = InspectorObject::create();
    1787     ${eventName}Message->setString("method", "$domainName.$eventName");
     1789    RefPtr<InspectorObject> jsonMessage = InspectorObject::create();
     1790    jsonMessage->setString("method", "$domainName.$eventName");
    17881791$code    if (m_inspectorFrontendChannel)
    1789         m_inspectorFrontendChannel->sendMessageToFrontend(${eventName}Message->toJSONString());
     1792        m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
     1793}
     1794""")
     1795
     1796    callback_method = string.Template(
     1797"""InspectorBackendDispatcher::$agentName::$callbackName::$callbackName(PassRefPtr<InspectorBackendDispatcherImpl> backendImpl, int id) : CallbackBase(backendImpl, id) {}
     1798
     1799void InspectorBackendDispatcher::$agentName::$callbackName::sendSuccess($parameters)
     1800{
     1801    RefPtr<InspectorObject> jsonMessage = InspectorObject::create();
     1802$code    sendIfActive(jsonMessage, ErrorString());
    17901803}
    17911804""")
     
    18461859typedef String ErrorString;
    18471860
     1861class InspectorBackendDispatcherImpl;
     1862
    18481863class InspectorBackendDispatcher: public RefCounted<InspectorBackendDispatcher> {
    18491864public:
    18501865    static PassRefPtr<InspectorBackendDispatcher> create(InspectorFrontendChannel* inspectorFrontendChannel);
    18511866    virtual ~InspectorBackendDispatcher() { }
     1867
     1868    class CallbackBase: public RefCounted<CallbackBase> {
     1869    public:
     1870        CallbackBase(PassRefPtr<InspectorBackendDispatcherImpl> backendImpl, int id);
     1871        virtual ~CallbackBase();
     1872        void sendFailure(const ErrorString&);
     1873        bool isActive();
     1874
     1875    protected:
     1876        void sendIfActive(PassRefPtr<InspectorObject> partialMessage, const ErrorString& invocationError);
     1877
     1878    private:
     1879        void disable() { m_alreadySent = true; }
     1880
     1881        RefPtr<InspectorBackendDispatcherImpl> m_backendImpl;
     1882        int m_id;
     1883        bool m_alreadySent;
     1884
     1885        friend class InspectorBackendDispatcherImpl;
     1886    };
    18521887
    18531888$agentInterfaces
     
    19211956    using InspectorBackendDispatcher::reportProtocolError;
    19221957
     1958    void sendResponse(long callId, PassRefPtr<InspectorObject> result, const ErrorString& invocationError);
     1959    bool isActive() { return m_inspectorFrontendChannel; }
     1960
    19231961$setters
    19241962private:
     
    20182056        return;
    20192057    }
     2058    sendResponse(callId, result, invocationError);
     2059}
     2060
     2061void InspectorBackendDispatcherImpl::sendResponse(long callId, PassRefPtr<InspectorObject> result, const ErrorString& invocationError)
     2062{
    20202063    if (invocationError.length()) {
    20212064        reportProtocolError(&callId, ServerError, invocationError);
     
    21552198}
    21562199
     2200InspectorBackendDispatcher::CallbackBase::CallbackBase(PassRefPtr<InspectorBackendDispatcherImpl> backendImpl, int id)
     2201    : m_backendImpl(backendImpl), m_id(id), m_alreadySent(false) {}
     2202
     2203InspectorBackendDispatcher::CallbackBase::~CallbackBase() {}
     2204
     2205void InspectorBackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
     2206{
     2207    ASSERT(error.length());
     2208    sendIfActive(0, error);
     2209}
     2210
     2211bool InspectorBackendDispatcher::CallbackBase::isActive()
     2212{
     2213    return !m_alreadySent && m_backendImpl->isActive();
     2214}
     2215
     2216void InspectorBackendDispatcher::CallbackBase::sendIfActive(PassRefPtr<InspectorObject> partialMessage, const ErrorString& invocationError)
     2217{
     2218    if (m_alreadySent)
     2219        return;
     2220    m_backendImpl->sendResponse(m_id, partialMessage, invocationError);
     2221    m_alreadySent = true;
     2222}
     2223
    21572224COMPILE_ASSERT(static_cast<int>(InspectorBackendDispatcher::kMethodNamesEnumSize) == WTF_ARRAY_LENGTH(InspectorBackendDispatcher::commandNames), command_name_array_problem);
    21582225
     
    27282795        event_name = json_event["name"]
    27292796
    2730         parameter_list = []
    2731         method_line_list = []
    2732         backend_js_event_param_list = []
    27332797        ad_hoc_type_output = []
    27342798        frontend_method_declaration_lines.append(ad_hoc_type_output)
    27352799        ad_hoc_type_writer = Writer(ad_hoc_type_output, "        ")
    2736         if "parameters" in json_event:
    2737             method_line_list.append("    RefPtr<InspectorObject> paramsObject = InspectorObject::create();\n")
    2738             for json_parameter in json_event["parameters"]:
    2739                 parameter_name = json_parameter["name"]
    2740 
    2741                 param_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_parameter, event_name, domain_name, ad_hoc_type_writer, "")
    2742 
    2743                 raw_type = param_type_binding.reduce_to_raw_type()
    2744                 raw_type_binding = RawTypeBinding(raw_type)
    2745 
    2746                 optional = bool(json_parameter.get("optional"))
    2747 
    2748                 setter_type = raw_type.get_setter_name()
    2749 
    2750                 type_model = param_type_binding.get_type_model()
    2751                 raw_type_model = raw_type_binding.get_type_model()
    2752                 if optional:
    2753                     type_model = type_model.get_optional()
    2754                     raw_type_model = raw_type_model.get_optional()
    2755 
    2756                 annotated_type = type_model.get_input_param_type_text()
    2757                 mode_type_binding = param_type_binding
    2758 
    2759                 parameter_list.append("%s %s" % (annotated_type, parameter_name))
    2760 
    2761                 setter_argument = raw_type_model.get_event_setter_expression_pattern() % parameter_name
    2762                 if mode_type_binding.get_setter_value_expression_pattern():
    2763                     setter_argument = mode_type_binding.get_setter_value_expression_pattern() % setter_argument
    2764 
    2765                 setter_code = "    paramsObject->set%s(\"%s\", %s);\n" % (setter_type, parameter_name, setter_argument)
    2766                 if optional:
    2767                     setter_code = ("    if (%s)\n    " % parameter_name) + setter_code
    2768                 method_line_list.append(setter_code)
    2769 
     2800
     2801        decl_parameter_list = []
     2802
     2803        json_parameters = json_event.get("parameters")
     2804        Generator.generate_send_method(json_parameters, event_name, domain_name, ad_hoc_type_writer,
     2805                                       decl_parameter_list,
     2806                                       Generator.EventMethodStructTemplate,
     2807                                       Generator.frontend_method_list, Templates.frontend_method, {"eventName": event_name})
     2808
     2809        backend_js_event_param_list = []
     2810        if json_parameters:
     2811            for parameter in json_parameters:
     2812                parameter_name = parameter["name"]
    27702813                backend_js_event_param_list.append("\"%s\"" % parameter_name)
    2771             method_line_list.append("    %sMessage->setObject(\"params\", paramsObject);\n" % event_name)
     2814
    27722815        frontend_method_declaration_lines.append(
    2773             "        void %s(%s);\n" % (event_name, ", ".join(parameter_list)))
    2774 
    2775         Generator.frontend_method_list.append(Templates.frontend_method.substitute(None,
    2776             domainName=domain_name, eventName=event_name,
    2777             parameters=", ".join(parameter_list),
    2778             code="".join(method_line_list)))
     2816            "        void %s(%s);\n" % (event_name, ", ".join(decl_parameter_list)))
    27792817
    27802818        Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerEvent(\"%s.%s\", [%s]);\n" % (
    27812819            domain_name, event_name, ", ".join(backend_js_event_param_list)))
     2820
     2821    class EventMethodStructTemplate:
     2822        @staticmethod
     2823        def append_prolog(line_list):
     2824            line_list.append("    RefPtr<InspectorObject> paramsObject = InspectorObject::create();\n")
     2825
     2826        @staticmethod
     2827        def append_epilog(line_list):
     2828            line_list.append("    jsonMessage->setObject(\"params\", paramsObject);\n")
     2829
     2830        container_name = "paramsObject"
    27822831
    27832832    @staticmethod
     
    28012850        agent_call_param_list = []
    28022851        response_cook_list = []
    2803         backend_js_reply_param_list = []
    28042852        request_message_param = ""
    28052853        js_parameters_text = ""
     
    28562904
    28572905        response_cook_text = ""
    2858         js_reply_list = "[]"
     2906        if json_command.get("async") == True:
     2907            callback_name = Capitalizer.lower_camel_case_to_upper(json_command_name) + "Callback"
     2908
     2909            callback_output = []
     2910            callback_writer = Writer(callback_output, ad_hoc_type_writer.get_indent())
     2911
     2912            decl_parameter_list = []
     2913            Generator.generate_send_method(json_command.get("returns"), json_command_name, domain_name, ad_hoc_type_writer,
     2914                                           decl_parameter_list,
     2915                                           Generator.CallbackMethodStructTemplate,
     2916                                           Generator.backend_method_implementation_list, Templates.callback_method,
     2917                                           {"callbackName": callback_name, "agentName": agent_interface_name})
     2918
     2919            callback_writer.newline("class " + callback_name + " : public CallbackBase {\n")
     2920            callback_writer.newline("public:\n")
     2921            callback_writer.newline("    " + callback_name + "(PassRefPtr<InspectorBackendDispatcherImpl>, int id);\n")
     2922            callback_writer.newline("    void sendSuccess(" + ", ".join(decl_parameter_list) + ");\n")
     2923            callback_writer.newline("};\n")
     2924
     2925            ad_hoc_type_output.append(callback_output)
     2926
     2927            method_out_code += "    RefPtr<" + agent_interface_name + "::" + callback_name + "> callback = adoptRef(new " + agent_interface_name + "::" + callback_name + "(this, callId));\n"
     2928            agent_call_param_list.append(", callback")
     2929            response_cook_text += "        if (!error.length()) \n"
     2930            response_cook_text += "            return;\n"
     2931            response_cook_text += "        callback->disable();\n"
     2932            Generator.backend_agent_interface_list.append(", PassRefPtr<%s> callback" % callback_name)
     2933        else:
     2934            if "returns" in json_command:
     2935                method_out_code += "\n"
     2936                for json_return in json_command["returns"]:
     2937
     2938                    json_return_name = json_return["name"]
     2939
     2940                    optional = bool(json_return.get("optional"))
     2941
     2942                    return_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_return, json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")
     2943
     2944                    raw_type = return_type_binding.reduce_to_raw_type()
     2945                    setter_type = raw_type.get_setter_name()
     2946                    initializer = raw_type.get_c_initializer()
     2947
     2948                    type_model = return_type_binding.get_type_model()
     2949                    if optional:
     2950                        type_model = type_model.get_optional()
     2951
     2952                    code = "    %s out_%s;\n" % (type_model.get_command_return_pass_model().get_return_var_type(), json_return_name)
     2953                    param = ", %sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
     2954                    var_name = "out_%s" % json_return_name
     2955                    setter_argument = type_model.get_command_return_pass_model().get_output_to_raw_expression() % var_name
     2956                    if return_type_binding.get_setter_value_expression_pattern():
     2957                        setter_argument = return_type_binding.get_setter_value_expression_pattern() % setter_argument
     2958
     2959                    cook = "            result->set%s(\"%s\", %s);\n" % (setter_type, json_return_name,
     2960                                                                         setter_argument)
     2961
     2962                    set_condition_pattern = type_model.get_command_return_pass_model().get_set_return_condition()
     2963                    if set_condition_pattern:
     2964                        cook = ("            if (%s)\n    " % (set_condition_pattern % var_name)) + cook
     2965                    annotated_type = type_model.get_command_return_pass_model().get_output_parameter_type()
     2966
     2967                    param_name = "out_%s" % json_return_name
     2968                    if optional:
     2969                        param_name = "opt_" + param_name
     2970
     2971                    Generator.backend_agent_interface_list.append(", %s %s" % (annotated_type, param_name))
     2972                    response_cook_list.append(cook)
     2973
     2974                    method_out_code += code
     2975                    agent_call_param_list.append(param)
     2976
     2977                response_cook_text = "".join(response_cook_list)
     2978
     2979                if len(response_cook_text) != 0:
     2980                    response_cook_text = "        if (!error.length()) {\n" + response_cook_text + "        }"
     2981
     2982        backend_js_reply_param_list = []
    28592983        if "returns" in json_command:
    2860             method_out_code += "\n"
    28612984            for json_return in json_command["returns"]:
    2862 
    28632985                json_return_name = json_return["name"]
    2864 
    2865                 optional = bool(json_return.get("optional"))
    2866 
    2867                 return_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_return, json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")
    2868 
    2869                 raw_type = return_type_binding.reduce_to_raw_type()
    2870                 setter_type = raw_type.get_setter_name()
    2871                 initializer = raw_type.get_c_initializer()
    2872 
    2873                 type_model = return_type_binding.get_type_model()
    2874                 if optional:
    2875                     type_model = type_model.get_optional()
    2876 
    2877                 code = "    %s out_%s;\n" % (type_model.get_command_return_pass_model().get_return_var_type(), json_return_name)
    2878                 param = ", %sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
    2879                 var_name = "out_%s" % json_return_name
    2880                 setter_argument = type_model.get_command_return_pass_model().get_output_to_raw_expression() % var_name
    2881                 if return_type_binding.get_setter_value_expression_pattern():
    2882                     setter_argument = return_type_binding.get_setter_value_expression_pattern() % setter_argument
    2883 
    2884                 cook = "            result->set%s(\"%s\", %s);\n" % (setter_type, json_return_name,
    2885                                                                  setter_argument)
    2886 
    2887                 set_condition_pattern = type_model.get_command_return_pass_model().get_set_return_condition()
    2888                 if set_condition_pattern:
    2889                     cook = ("            if (%s)\n    " % (set_condition_pattern % var_name)) + cook
    2890                 annotated_type = type_model.get_command_return_pass_model().get_output_parameter_type()
    2891 
    2892                 param_name = "out_%s" % json_return_name
    2893                 if optional:
    2894                     param_name = "opt_" + param_name
    2895 
    2896                 Generator.backend_agent_interface_list.append(", %s %s" % (annotated_type, param_name))
    2897                 response_cook_list.append(cook)
    2898 
    2899                 method_out_code += code
    2900                 agent_call_param_list.append(param)
    2901 
    29022986                backend_js_reply_param_list.append("\"%s\"" % json_return_name)
    29032987
    2904             js_reply_list = "[%s]" % ", ".join(backend_js_reply_param_list)
    2905 
    2906             response_cook_text = "".join(response_cook_list)
    2907 
    2908             if len(response_cook_text) != 0:
    2909                 response_cook_text = "        if (!error.length()) {\n" + response_cook_text + "        }"
     2988        js_reply_list = "[%s]" % ", ".join(backend_js_reply_param_list)
    29102989
    29112990        Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
     
    29233002        Generator.backend_agent_interface_list.append(") = 0;\n")
    29243003
     3004    class CallbackMethodStructTemplate:
     3005        @staticmethod
     3006        def append_prolog(line_list):
     3007            pass
     3008
     3009        @staticmethod
     3010        def append_epilog(line_list):
     3011            pass
     3012
     3013        container_name = "jsonMessage"
     3014
     3015    # Generates common code for event sending and callback response data sending.
     3016    @staticmethod
     3017    def generate_send_method(parameters, event_name, domain_name, ad_hoc_type_writer, decl_parameter_list,
     3018                             method_struct_template,
     3019                             generator_method_list, method_template, template_params):
     3020        method_line_list = []
     3021        if parameters:
     3022            method_struct_template.append_prolog(method_line_list)
     3023            for json_parameter in parameters:
     3024                parameter_name = json_parameter["name"]
     3025
     3026                param_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_parameter, event_name, domain_name, ad_hoc_type_writer, "")
     3027
     3028                raw_type = param_type_binding.reduce_to_raw_type()
     3029                raw_type_binding = RawTypeBinding(raw_type)
     3030
     3031                optional = bool(json_parameter.get("optional"))
     3032
     3033                setter_type = raw_type.get_setter_name()
     3034
     3035                type_model = param_type_binding.get_type_model()
     3036                raw_type_model = raw_type_binding.get_type_model()
     3037                if optional:
     3038                    type_model = type_model.get_optional()
     3039                    raw_type_model = raw_type_model.get_optional()
     3040
     3041                annotated_type = type_model.get_input_param_type_text()
     3042                mode_type_binding = param_type_binding
     3043
     3044                decl_parameter_list.append("%s %s" % (annotated_type, parameter_name))
     3045
     3046                setter_argument = raw_type_model.get_event_setter_expression_pattern() % parameter_name
     3047                if mode_type_binding.get_setter_value_expression_pattern():
     3048                    setter_argument = mode_type_binding.get_setter_value_expression_pattern() % setter_argument
     3049
     3050                setter_code = "    %s->set%s(\"%s\", %s);\n" % (method_struct_template.container_name, setter_type, parameter_name, setter_argument)
     3051                if optional:
     3052                    setter_code = ("    if (%s)\n    " % parameter_name) + setter_code
     3053                method_line_list.append(setter_code)
     3054
     3055            method_struct_template.append_epilog(method_line_list)
     3056
     3057        generator_method_list.append(method_template.substitute(None,
     3058            domainName=domain_name,
     3059            parameters=", ".join(decl_parameter_list),
     3060            code="".join(method_line_list), **template_params))
     3061
    29253062    @staticmethod
    29263063    def resolve_type_and_generate_ad_hoc(json_param, method_name, domain_name, ad_hoc_type_writer, container_relative_name_prefix_param):
Note: See TracChangeset for help on using the changeset viewer.