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