1# Copyright (C) 2010, 2011 Apple Inc. All rights reserved. 2# 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions 5# are met: 6# 1. Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# 2. Redistributions in binary form must reproduce the above copyright 9# notice, this list of conditions and the following disclaimer in the 10# documentation and/or other materials provided with the distribution. 11# 12# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 13# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 16# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 23import collections 24import re 25import sys 26from webkit2 import parser 27 28WANTS_CONNECTION_ATTRIBUTE = 'WantsConnection' 29LEGACY_RECEIVER_ATTRIBUTE = 'LegacyReceiver' 30DELAYED_ATTRIBUTE = 'Delayed' 31VARIADIC_ATTRIBUTE = 'Variadic' 32 33_license_header = """/* 34 * Copyright (C) 2010 Apple Inc. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 47 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 48 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR 49 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 52 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 53 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57""" 58 59 60def messages_header_filename(receiver): 61 return '%sMessages.h' % receiver.name 62 63 64def surround_in_condition(string, condition): 65 if not condition: 66 return string 67 return '#if %s\n%s#endif\n' % (condition, string) 68 69 70def function_parameter_type(type): 71 # Don't use references for built-in types. 72 builtin_types = frozenset([ 73 'bool', 74 'float', 75 'double', 76 'uint8_t', 77 'uint16_t', 78 'uint32_t', 79 'uint64_t', 80 'int8_t', 81 'int16_t', 82 'int32_t', 83 'int64_t', 84 ]) 85 86 if type in builtin_types: 87 return type 88 89 return 'const %s&' % type 90 91 92def reply_parameter_type(type): 93 return '%s&' % type 94 95 96def arguments_type(message): 97 return 'std::tuple<%s>' % ', '.join(function_parameter_type(parameter.type) for parameter in message.parameters) 98 99 100def reply_type(message): 101 return 'IPC::Arguments<%s>' % (', '.join(reply_parameter_type(parameter.type) for parameter in message.reply_parameters)) 102 103 104def decode_type(message): 105 parameters = message.parameters 106 107 if message.has_attribute(VARIADIC_ATTRIBUTE): 108 parameters = parameters[:-1] 109 110 return 'std::tuple<%s>' % ', '.join(parameter.type for parameter in parameters) 111 112 113def message_to_struct_declaration(message): 114 result = [] 115 function_parameters = [(function_parameter_type(x.type), x.name) for x in message.parameters] 116 result.append('class %s {\n' % message.name) 117 result.append('public:\n') 118 result.append(' typedef %s DecodeType;\n' % decode_type(message)) 119 result.append('\n') 120 result.append(' static IPC::StringReference receiverName() { return messageReceiverName(); }\n') 121 result.append(' static IPC::StringReference name() { return IPC::StringReference("%s"); }\n' % message.name) 122 result.append(' static const bool isSync = %s;\n' % ('false', 'true')[message.reply_parameters != None]) 123 result.append('\n') 124 if message.reply_parameters != None: 125 if message.has_attribute(DELAYED_ATTRIBUTE): 126 send_parameters = [(function_parameter_type(x.type), x.name) for x in message.reply_parameters] 127 result.append(' struct DelayedReply : public ThreadSafeRefCounted<DelayedReply> {\n') 128 result.append(' DelayedReply(PassRefPtr<IPC::Connection>, std::unique_ptr<IPC::MessageEncoder>);\n') 129 result.append(' ~DelayedReply();\n') 130 result.append('\n') 131 result.append(' bool send(%s);\n' % ', '.join([' '.join(x) for x in send_parameters])) 132 result.append('\n') 133 result.append(' private:\n') 134 result.append(' RefPtr<IPC::Connection> m_connection;\n') 135 result.append(' std::unique_ptr<IPC::MessageEncoder> m_encoder;\n') 136 result.append(' };\n\n') 137 138 result.append(' typedef %s Reply;\n' % reply_type(message)) 139 140 if len(function_parameters): 141 result.append(' %s%s(%s)' % (len(function_parameters) == 1 and 'explicit ' or '', message.name, ', '.join([' '.join(x) for x in function_parameters]))) 142 result.append('\n : m_arguments(%s)\n' % ', '.join([x[1] for x in function_parameters])) 143 result.append(' {\n') 144 result.append(' }\n\n') 145 result.append(' const %s& arguments() const\n' % arguments_type(message)) 146 result.append(' {\n') 147 result.append(' return m_arguments;\n') 148 result.append(' }\n') 149 result.append('\n') 150 result.append('private:\n') 151 result.append(' %s m_arguments;\n' % arguments_type(message)) 152 result.append('};\n') 153 return surround_in_condition(''.join(result), message.condition) 154 155 156def struct_or_class(namespace, type): 157 structs = frozenset([ 158 'WebCore::Animation', 159 'WebCore::EditorCommandsForKeyEvent', 160 'WebCore::CompositionUnderline', 161 'WebCore::Cookie', 162 'WebCore::FloatPoint3D', 163 'WebCore::FileChooserSettings', 164 'WebCore::GrammarDetail', 165 'WebCore::Highlight', 166 'WebCore::IDBDatabaseMetadata', 167 'WebCore::IDBGetResult', 168 'WebCore::IDBIndexMetadata', 169 'WebCore::IDBKeyData', 170 'WebCore::IDBKeyRangeData', 171 'WebCore::IDBObjectStoreMetadata', 172 'WebCore::IdentityTransformOperation', 173 'WebCore::KeypressCommand', 174 'WebCore::Length', 175 'WebCore::MatrixTransformOperation', 176 'WebCore::Matrix3DTransformOperation', 177 'WebCore::NotificationContents', 178 'WebCore::PasteboardImage', 179 'WebCore::PasteboardWebContent', 180 'WebCore::PerspectiveTransformOperation', 181 'WebCore::PluginInfo', 182 'WebCore::PrintInfo', 183 'WebCore::RotateTransformOperation', 184 'WebCore::ScaleTransformOperation', 185 'WebCore::SkewTransformOperation', 186 'WebCore::TimingFunction', 187 'WebCore::TransformationMatrix', 188 'WebCore::TransformOperation', 189 'WebCore::TransformOperations', 190 'WebCore::TranslateTransformOperation', 191 'WebCore::ViewportArguments', 192 'WebCore::ViewportAttributes', 193 'WebCore::WindowFeatures', 194 'WebKit::AssistedNodeInformation', 195 'WebKit::AttributedString', 196 'WebKit::BackForwardListItemState', 197 'WebKit::ColorSpaceData', 198 'WebKit::ContextMenuState', 199 'WebKit::DatabaseProcessCreationParameters', 200 'WebKit::DictionaryPopupInfo', 201 'WebKit::DrawingAreaInfo', 202 'WebKit::EditingRange', 203 'WebKit::EditorState', 204 'WebKit::InteractionInformationAtPosition', 205 'WebKit::NavigationActionData', 206 'WebKit::NetworkProcessCreationParameters', 207 'WebKit::PageState', 208 'WebKit::PlatformPopupMenuData', 209 'WebKit::PluginCreationParameters', 210 'WebKit::PluginProcessCreationParameters', 211 'WebKit::PrintInfo', 212 'WebKit::SecurityOriginData', 213 'WebKit::StatisticsData', 214 'WebKit::TextCheckerState', 215 'WebKit::WKOptionItem', 216 'WebKit::WebNavigationDataStore', 217 'WebKit::WebPageCreationParameters', 218 'WebKit::WebPreferencesStore', 219 'WebKit::WebProcessCreationParameters', 220 'WebKit::WebScriptMessageHandlerHandle', 221 'WebKit::WindowGeometry', 222 ]) 223 224 qualified_name = '%s::%s' % (namespace, type) 225 if qualified_name in structs: 226 return 'struct %s' % type 227 228 return 'class %s' % type 229 230def forward_declarations_for_namespace(namespace, types): 231 result = [] 232 result.append('namespace %s {\n' % namespace) 233 result += [' %s;\n' % struct_or_class(namespace, x) for x in types] 234 result.append('}\n') 235 return ''.join(result) 236 237 238def forward_declarations_and_headers(receiver): 239 types_by_namespace = collections.defaultdict(set) 240 241 headers = set([ 242 '"Arguments.h"', 243 '"MessageEncoder.h"', 244 '"StringReference.h"', 245 ]) 246 247 non_template_wtf_types = frozenset([ 248 'String', 249 ]) 250 251 for message in receiver.messages: 252 if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE): 253 headers.add('<wtf/ThreadSafeRefCounted.h>') 254 types_by_namespace['IPC'].update(['Connection']) 255 256 for parameter in receiver.iterparameters(): 257 type = parameter.type 258 259 if type.find('<') != -1: 260 # Don't forward declare class templates. 261 headers.update(headers_for_type(type)) 262 continue 263 264 split = type.split('::') 265 266 # Handle WTF types even if the WTF:: prefix is not given 267 if split[0] in non_template_wtf_types: 268 split.insert(0, 'WTF') 269 270 if len(split) == 2: 271 namespace = split[0] 272 inner_type = split[1] 273 types_by_namespace[namespace].add(inner_type) 274 elif len(split) > 2: 275 # We probably have a nested struct, which means we can't forward declare it. 276 # Include its header instead. 277 headers.update(headers_for_type(type)) 278 279 forward_declarations = '\n'.join([forward_declarations_for_namespace(namespace, types) for (namespace, types) in sorted(types_by_namespace.items())]) 280 headers = ['#include %s\n' % header for header in sorted(headers)] 281 282 return (forward_declarations, headers) 283 284def generate_messages_header(file): 285 receiver = parser.parse(file) 286 header_guard = messages_header_filename(receiver).replace('.', '_') 287 288 result = [] 289 290 result.append(_license_header) 291 292 result.append('#ifndef %s\n' % header_guard) 293 result.append('#define %s\n\n' % header_guard) 294 295 if receiver.condition: 296 result.append('#if %s\n\n' % receiver.condition) 297 298 forward_declarations, headers = forward_declarations_and_headers(receiver) 299 300 result += headers 301 result.append('\n') 302 303 result.append(forward_declarations) 304 result.append('\n') 305 306 result.append('namespace Messages {\nnamespace %s {\n' % receiver.name) 307 result.append('\n') 308 result.append('static inline IPC::StringReference messageReceiverName()\n') 309 result.append('{\n') 310 result.append(' return IPC::StringReference("%s");\n' % receiver.name) 311 result.append('}\n') 312 result.append('\n') 313 result.append('\n'.join([message_to_struct_declaration(x) for x in receiver.messages])) 314 result.append('\n') 315 result.append('} // namespace %s\n} // namespace Messages\n' % receiver.name) 316 317 if receiver.condition: 318 result.append('\n#endif // %s\n' % receiver.condition) 319 320 result.append('\n#endif // %s\n' % header_guard) 321 322 return ''.join(result) 323 324 325def handler_function(receiver, message): 326 if message.name.find('URL') == 0: 327 return '%s::%s' % (receiver.name, 'url' + message.name[3:]) 328 return '%s::%s' % (receiver.name, message.name[0].lower() + message.name[1:]) 329 330 331def async_message_statement(receiver, message): 332 dispatch_function_args = ['decoder', 'this', '&%s' % handler_function(receiver, message)] 333 334 dispatch_function = 'handleMessage' 335 if message.has_attribute(VARIADIC_ATTRIBUTE): 336 dispatch_function += 'Variadic' 337 338 if message.has_attribute(WANTS_CONNECTION_ATTRIBUTE): 339 dispatch_function_args.insert(0, 'connection') 340 341 result = [] 342 result.append(' if (decoder.messageName() == Messages::%s::%s::name()) {\n' % (receiver.name, message.name)) 343 result.append(' IPC::%s<Messages::%s::%s>(%s);\n' % (dispatch_function, receiver.name, message.name, ', '.join(dispatch_function_args))) 344 result.append(' return;\n') 345 result.append(' }\n') 346 return surround_in_condition(''.join(result), message.condition) 347 348 349def sync_message_statement(receiver, message): 350 dispatch_function = 'handleMessage' 351 if message.has_attribute(DELAYED_ATTRIBUTE): 352 dispatch_function += 'Delayed' 353 if message.has_attribute(VARIADIC_ATTRIBUTE): 354 dispatch_function += 'Variadic' 355 356 wants_connection = message.has_attribute(DELAYED_ATTRIBUTE) or message.has_attribute(WANTS_CONNECTION_ATTRIBUTE) 357 358 result = [] 359 result.append(' if (decoder.messageName() == Messages::%s::%s::name()) {\n' % (receiver.name, message.name)) 360 result.append(' IPC::%s<Messages::%s::%s>(%sdecoder, %sreplyEncoder, this, &%s);\n' % (dispatch_function, receiver.name, message.name, 'connection, ' if wants_connection else '', '' if message.has_attribute(DELAYED_ATTRIBUTE) else '*', handler_function(receiver, message))) 361 result.append(' return;\n') 362 result.append(' }\n') 363 return surround_in_condition(''.join(result), message.condition) 364 365 366def class_template_headers(template_string): 367 template_string = template_string.strip() 368 369 class_template_types = { 370 'Vector': {'headers': ['<wtf/Vector.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']}, 371 'HashMap': {'headers': ['<wtf/HashMap.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']}, 372 'std::pair': {'headers': ['<utility>'], 'argument_coder_headers': ['"ArgumentCoders.h"']}, 373 } 374 375 match = re.match('(?P<template_name>.+?)<(?P<parameter_string>.+)>', template_string) 376 if not match: 377 return {'header_infos':[], 'types':[template_string]} 378 379 template_name = match.groupdict()['template_name'] 380 if template_name not in class_template_types: 381 sys.stderr.write("Error: no class template type is defined for '%s'\n" % (template_string)) 382 sys.exit(1) 383 384 header_infos = [class_template_types[template_name]] 385 types = [] 386 387 for parameter in parser.split_parameters_string(match.groupdict()['parameter_string']): 388 parameter_header_infos_and_types = class_template_headers(parameter) 389 390 header_infos += parameter_header_infos_and_types['header_infos']; 391 types += parameter_header_infos_and_types['types'] 392 393 return {'header_infos':header_infos, 'types':types} 394 395 396def argument_coder_headers_for_type(type): 397 header_infos_and_types = class_template_headers(type) 398 399 special_cases = { 400 'String': '"ArgumentCoders.h"', 401 'WebKit::InjectedBundleUserMessageEncoder': '"InjectedBundleUserMessageCoders.h"', 402 'WebKit::WebContextUserMessageEncoder': '"WebContextUserMessageCoders.h"', 403 'WebKit::ScriptMessageHandlerHandle': '"WebScriptMessageHandler.h"', 404 } 405 406 headers = [] 407 for header_info in header_infos_and_types['header_infos']: 408 headers += header_info['argument_coder_headers'] 409 410 for type in header_infos_and_types['types']: 411 if type in special_cases: 412 headers.append(special_cases[type]) 413 continue 414 415 split = type.split('::') 416 if len(split) < 2: 417 continue 418 if split[0] == 'WebCore': 419 headers.append('"WebCoreArgumentCoders.h"') 420 421 return headers 422 423def headers_for_type(type): 424 header_infos_and_types = class_template_headers(type) 425 426 special_cases = { 427 'String': ['<wtf/text/WTFString.h>'], 428 'WebCore::CompositionUnderline': ['<WebCore/Editor.h>'], 429 'WebCore::GrammarDetail': ['<WebCore/TextCheckerClient.h>'], 430 'WebCore::GraphicsLayerAnimations': ['<WebCore/GraphicsLayerAnimation.h>'], 431 'WebCore::KeyframeValueList': ['<WebCore/GraphicsLayer.h>'], 432 'WebCore::KeypressCommand': ['<WebCore/KeyboardEvent.h>'], 433 'WebCore::FileChooserSettings': ['<WebCore/FileChooser.h>'], 434 'WebCore::Highlight': ['<WebCore/InspectorOverlay.h>'], 435 'WebCore::PluginInfo': ['<WebCore/PluginData.h>'], 436 'WebCore::PasteboardImage': ['<WebCore/Pasteboard.h>'], 437 'WebCore::PasteboardWebContent': ['<WebCore/Pasteboard.h>'], 438 'WebCore::TextCheckingRequestData': ['<WebCore/TextChecking.h>'], 439 'WebCore::TextCheckingResult': ['<WebCore/TextCheckerClient.h>'], 440 'WebCore::ViewportAttributes': ['<WebCore/ViewportArguments.h>'], 441 'WebKit::BackForwardListItemState': ['"SessionState.h"'], 442 'WebKit::InjectedBundleUserMessageEncoder': [], 443 'WebKit::PageState': ['"SessionState.h"'], 444 'WebKit::WebContextUserMessageEncoder': [], 445 'WebKit::WebGestureEvent': ['"WebEvent.h"'], 446 'WebKit::WebKeyboardEvent': ['"WebEvent.h"'], 447 'WebKit::WebMouseEvent': ['"WebEvent.h"'], 448 'WebKit::WebTouchEvent': ['"WebEvent.h"'], 449 'WebKit::WebWheelEvent': ['"WebEvent.h"'], 450 'WebKit::WebScriptMessageHandlerHandle': ['"WebScriptMessageHandler.h"'], 451 } 452 453 headers = [] 454 for header_info in header_infos_and_types['header_infos']: 455 headers += header_info['headers'] 456 457 for type in header_infos_and_types['types']: 458 if type in special_cases: 459 headers += special_cases[type] 460 continue 461 462 # We assume that we must include a header for a type iff it has a scope 463 # resolution operator (::). 464 split = type.split('::') 465 if len(split) < 2: 466 continue 467 468 if split[0] == 'WebKit' or split[0] == 'IPC': 469 headers.append('"%s.h"' % split[1]) 470 else: 471 headers.append('<%s/%s.h>' % tuple(split[0:2])) 472 473 return headers 474 475def generate_message_handler(file): 476 receiver = parser.parse(file) 477 header_conditions = { 478 '"%s"' % messages_header_filename(receiver): [None], 479 '"HandleMessage.h"': [None], 480 '"MessageDecoder.h"': [None], 481 } 482 483 type_conditions = {} 484 for parameter in receiver.iterparameters(): 485 if not parameter.type in type_conditions: 486 type_conditions[parameter.type] = [] 487 488 if not parameter.condition in type_conditions[parameter.type]: 489 type_conditions[parameter.type].append(parameter.condition) 490 491 for parameter in receiver.iterparameters(): 492 type = parameter.type 493 conditions = type_conditions[type] 494 495 argument_encoder_headers = argument_coder_headers_for_type(type) 496 if argument_encoder_headers: 497 for header in argument_encoder_headers: 498 if header not in header_conditions: 499 header_conditions[header] = [] 500 header_conditions[header].extend(conditions) 501 502 type_headers = headers_for_type(type) 503 for header in type_headers: 504 if header not in header_conditions: 505 header_conditions[header] = [] 506 header_conditions[header].extend(conditions) 507 508 for message in receiver.messages: 509 if message.reply_parameters is not None: 510 for reply_parameter in message.reply_parameters: 511 type = reply_parameter.type 512 argument_encoder_headers = argument_coder_headers_for_type(type) 513 if argument_encoder_headers: 514 for header in argument_encoder_headers: 515 if header not in header_conditions: 516 header_conditions[header] = [] 517 header_conditions[header].append(message.condition) 518 519 type_headers = headers_for_type(type) 520 for header in type_headers: 521 if header not in header_conditions: 522 header_conditions[header] = [] 523 header_conditions[header].append(message.condition) 524 525 526 result = [] 527 528 result.append(_license_header) 529 result.append('#include "config.h"\n') 530 result.append('\n') 531 532 if receiver.condition: 533 result.append('#if %s\n\n' % receiver.condition) 534 535 result.append('#include "%s.h"\n\n' % receiver.name) 536 for header in sorted(header_conditions): 537 if header_conditions[header] and not None in header_conditions[header]: 538 result.append('#if %s\n' % ' || '.join(set(header_conditions[header]))) 539 result += ['#include %s\n' % header] 540 result.append('#endif\n') 541 else: 542 result += ['#include %s\n' % header] 543 result.append('\n') 544 545 sync_delayed_messages = [] 546 for message in receiver.messages: 547 if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE): 548 sync_delayed_messages.append(message) 549 550 if sync_delayed_messages: 551 result.append('namespace Messages {\n\nnamespace %s {\n\n' % receiver.name) 552 553 for message in sync_delayed_messages: 554 send_parameters = [(function_parameter_type(x.type), x.name) for x in message.reply_parameters] 555 556 if message.condition: 557 result.append('#if %s\n\n' % message.condition) 558 559 result.append('%s::DelayedReply::DelayedReply(PassRefPtr<IPC::Connection> connection, std::unique_ptr<IPC::MessageEncoder> encoder)\n' % message.name) 560 result.append(' : m_connection(connection)\n') 561 result.append(' , m_encoder(WTF::move(encoder))\n') 562 result.append('{\n') 563 result.append('}\n') 564 result.append('\n') 565 result.append('%s::DelayedReply::~DelayedReply()\n' % message.name) 566 result.append('{\n') 567 result.append(' ASSERT(!m_connection);\n') 568 result.append('}\n') 569 result.append('\n') 570 result.append('bool %s::DelayedReply::send(%s)\n' % (message.name, ', '.join([' '.join(x) for x in send_parameters]))) 571 result.append('{\n') 572 result.append(' ASSERT(m_encoder);\n') 573 result += [' *m_encoder << %s;\n' % x.name for x in message.reply_parameters] 574 result.append(' bool _result = m_connection->sendSyncReply(WTF::move(m_encoder));\n') 575 result.append(' m_connection = nullptr;\n') 576 result.append(' return _result;\n') 577 result.append('}\n') 578 result.append('\n') 579 580 if message.condition: 581 result.append('#endif\n\n') 582 583 result.append('} // namespace %s\n\n} // namespace Messages\n\n' % receiver.name) 584 585 result.append('namespace WebKit {\n\n') 586 587 async_messages = [] 588 sync_messages = [] 589 for message in receiver.messages: 590 if message.reply_parameters is not None: 591 sync_messages.append(message) 592 else: 593 async_messages.append(message) 594 595 if async_messages: 596 if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): 597 result.append('void %s::didReceive%sMessage(IPC::Connection*, IPC::MessageDecoder& decoder)\n' % (receiver.name, receiver.name)) 598 else: 599 result.append('void %s::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)\n' % (receiver.name)) 600 601 result.append('{\n') 602 result += [async_message_statement(receiver, message) for message in async_messages] 603 if (receiver.superclass): 604 result.append(' %s::didReceiveMessage(connection, decoder);\n' % (receiver.superclass)) 605 else: 606 if not receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): 607 result.append(' UNUSED_PARAM(connection);\n') 608 result.append(' UNUSED_PARAM(decoder);\n') 609 result.append(' ASSERT_NOT_REACHED();\n') 610 result.append('}\n') 611 612 if sync_messages: 613 result.append('\n') 614 if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): 615 result.append('void %s::didReceiveSync%sMessage(IPC::Connection*%s, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)\n' % (receiver.name, receiver.name, ' connection' if sync_delayed_messages else '')) 616 else: 617 result.append('void %s::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)\n' % (receiver.name)) 618 result.append('{\n') 619 result += [sync_message_statement(receiver, message) for message in sync_messages] 620 if not receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): 621 result.append(' UNUSED_PARAM(connection);\n') 622 result.append(' UNUSED_PARAM(decoder);\n') 623 result.append(' UNUSED_PARAM(replyEncoder);\n') 624 result.append(' ASSERT_NOT_REACHED();\n') 625 result.append('}\n') 626 627 result.append('\n} // namespace WebKit\n') 628 629 if receiver.condition: 630 result.append('\n#endif // %s\n' % receiver.condition) 631 632 return ''.join(result) 633