Replace WTF::move with WTFMove
[WebKit-https.git] / Source / JavaScriptCore / inspector / scripts / codegen / generate_objc_frontend_dispatcher_implementation.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
4 # Copyright (c) 2014 University of Washington. All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 #    notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 #    notice, this list of conditions and the following disclaimer in the
13 #    documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 # THE POSSIBILITY OF SUCH DAMAGE.
26
27
28 import logging
29 import string
30 from string import Template
31
32 from cpp_generator import CppGenerator
33 from generator import Generator, ucfirst
34 from objc_generator import ObjCGenerator
35 from objc_generator_templates import ObjCGeneratorTemplates as ObjCTemplates
36
37 log = logging.getLogger('global')
38
39
40 class ObjCFrontendDispatcherImplementationGenerator(Generator):
41     def __init__(self, model, input_filepath):
42         Generator.__init__(self, model, input_filepath)
43
44     def output_filename(self):
45         return '%sEventDispatchers.mm' % ObjCGenerator.OBJC_PREFIX
46
47     def domains_to_generate(self):
48         return filter(ObjCGenerator.should_generate_domain_event_dispatcher_filter(self.model()), Generator.domains_to_generate(self))
49
50     def generate_output(self):
51         secondary_headers = [
52             '"%sEnumConversionHelpers.h"' % ObjCGenerator.OBJC_PREFIX,
53             '<JavaScriptCore/InspectorValues.h>',
54         ]
55
56         header_args = {
57             'primaryInclude': '"%sInternal.h"' % ObjCGenerator.OBJC_PREFIX,
58             'secondaryIncludes': '\n'.join(['#import %s' % header for header in secondary_headers]),
59         }
60
61         domains = self.domains_to_generate()
62         sections = []
63         sections.append(self.generate_license())
64         sections.append(Template(ObjCTemplates.ImplementationPrelude).substitute(None, **header_args))
65         sections.extend(map(self._generate_event_dispatcher_implementations, domains))
66         sections.append(Template(ObjCTemplates.ImplementationPostlude).substitute(None, **header_args))
67         return '\n\n'.join(sections)
68
69     def _generate_event_dispatcher_implementations(self, domain):
70         if not domain.events:
71             return ''
72
73         lines = []
74         objc_name = '%s%sDomainEventDispatcher' % (ObjCGenerator.OBJC_PREFIX, domain.domain_name)
75         lines.append('@implementation %s' % objc_name)
76         lines.append('{')
77         lines.append('    AugmentableInspectorController* _controller;')
78         lines.append('}')
79         lines.append('')
80         lines.append('- (instancetype)initWithController:(AugmentableInspectorController*)controller;')
81         lines.append('{')
82         lines.append('    self = [super init];')
83         lines.append('    if (!self)')
84         lines.append('        return nil;')
85         lines.append('    ASSERT(controller);')
86         lines.append('    _controller = controller;')
87         lines.append('    return self;')
88         lines.append('}')
89         lines.append('')
90         for event in domain.events:
91             lines.append(self._generate_event(domain, event))
92             lines.append('')
93         lines.append('@end')
94         return '\n'.join(lines)
95
96     def _generate_event(self, domain, event):
97         lines = []
98         lines.append(self._generate_event_signature(domain, event))
99         lines.append('{')
100         lines.append('    const FrontendRouter& router = _controller->frontendRouter();')
101         lines.append('')
102
103         required_pointer_parameters = filter(lambda parameter: not parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), event.event_parameters)
104         for parameter in required_pointer_parameters:
105             var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
106             lines.append('    THROW_EXCEPTION_FOR_REQUIRED_PARAMETER(%s, @"%s");' % (var_name, var_name))
107             objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type)
108             if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
109                 lines.append('    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
110
111         optional_pointer_parameters = filter(lambda parameter: parameter.is_optional and ObjCGenerator.is_type_objc_pointer_type(parameter.type), event.event_parameters)
112         for parameter in optional_pointer_parameters:
113             var_name = ObjCGenerator.identifier_to_objc_identifier(parameter.parameter_name)
114             lines.append('    THROW_EXCEPTION_FOR_BAD_OPTIONAL_PARAMETER(%s, @"%s");' % (var_name, var_name))
115             objc_array_class = ObjCGenerator.objc_class_for_array_type(parameter.type)
116             if objc_array_class and objc_array_class.startswith(ObjCGenerator.OBJC_PREFIX):
117                 lines.append('    THROW_EXCEPTION_FOR_BAD_TYPE_IN_OPTIONAL_ARRAY(%s, [%s class]);' % (var_name, objc_array_class))
118
119         if required_pointer_parameters or optional_pointer_parameters:
120             lines.append('')
121
122         lines.append('    Ref<InspectorObject> jsonMessage = InspectorObject::create();')
123         lines.append('    jsonMessage->setString(ASCIILiteral("method"), ASCIILiteral("%s.%s"));' % (domain.domain_name, event.event_name))
124         if event.event_parameters:
125             lines.extend(self._generate_event_out_parameters(domain, event))
126         lines.append('    router.sendEvent(jsonMessage->toJSONString());')
127         lines.append('}')
128         return '\n'.join(lines)
129
130     def _generate_event_signature(self, domain, event):
131         if not event.event_parameters:
132             return '- (void)%s' % event.event_name
133         pairs = []
134         for parameter in event.event_parameters:
135             param_name = parameter.parameter_name
136             pairs.append('%s:(%s)%s' % (param_name, ObjCGenerator.objc_type_for_param(domain, event.event_name, parameter), param_name))
137         pairs[0] = ucfirst(pairs[0])
138         return '- (void)%sWith%s' % (event.event_name, ' '.join(pairs))
139
140     def _generate_event_out_parameters(self, domain, event):
141         lines = []
142         lines.append('    Ref<InspectorObject> paramsObject = InspectorObject::create();')
143         for parameter in event.event_parameters:
144             keyed_set_method = CppGenerator.cpp_setter_method_for_type(parameter.type)
145             var_name = parameter.parameter_name
146             safe_var_name = '(*%s)' % var_name if parameter.is_optional else var_name
147             export_expression = ObjCGenerator.objc_protocol_export_expression_for_variable(parameter.type, safe_var_name)
148             if not parameter.is_optional:
149                 lines.append('    paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
150             else:
151                 lines.append('    if (%s)' % (parameter.parameter_name))
152                 lines.append('        paramsObject->%s(ASCIILiteral("%s"), %s);' % (keyed_set_method, parameter.parameter_name, export_expression))
153         lines.append('    jsonMessage->setObject(ASCIILiteral("params"), WTFMove(paramsObject));')
154         return lines