def test_duplicate_receivers(self): contents = """ messages -> WebPage { LoadURL(String url) }""" receiver = parser.parse(StringIO(contents)) self.assertEquals(receiver.name, 'WebPage') self.assertEquals(receiver.messages[0].name, 'LoadURL') other_contents = """ messages -> WebPage { LoadURL(String url) LoadURL2(String url) }""" other_receiver = parser.parse(StringIO(other_contents)) self.assertEquals(other_receiver.name, 'WebPage') self.assertEquals(other_receiver.messages[0].name, 'LoadURL') self.assertEquals(other_receiver.messages[1].name, 'LoadURL2') errors = model.check_global_model_inputs([receiver, other_receiver]) self.assertEquals(len(errors), 1) self.assertTrue("Duplicate" in errors[0])
def test_mismatch_message_attribute_sync(self): contents = """ messages -> WebPage { #if USE(COCOA) LoadURL(String url) Synchronous #endif #if USE(GTK) LoadURL(String url) #endif }""" receiver = parser.parse(StringIO(contents)) self.assertEquals(receiver.name, 'WebPage') self.assertEquals(receiver.messages[0].name, 'LoadURL') errors = model.check_global_model_inputs([receiver]) self.assertEquals(len(errors), 1) self.assertTrue("attribute mismatch" in errors[0])
def generate_messages_header(file): receiver = parser.parse(file) header_guard = messages_header_filename(receiver).replace('.', '_') result = [] result.append(_license_header) result.append('#ifndef %s\n' % header_guard) result.append('#define %s\n\n' % header_guard) if receiver.condition: result.append('#if %s\n\n' % receiver.condition) forward_declarations, headers = forward_declarations_and_headers(receiver) result += headers result.append('\n') result.append(forward_declarations) result.append('\n') result.append('namespace Messages {\nnamespace %s {\n' % receiver.name) result.append('\n') result.append('static inline IPC::StringReference messageReceiverName()\n') result.append('{\n') result.append(' return IPC::StringReference("%s");\n' % receiver.name) result.append('}\n') result.append('\n') result.append('\n'.join( [message_to_struct_declaration(x) for x in receiver.messages])) result.append('\n') result.append('} // namespace %s\n} // namespace Messages\n' % receiver.name) if receiver.condition: result.append('\n#endif // %s\n' % receiver.condition) result.append('\n#endif // %s\n' % header_guard) return ''.join(result)
def generate_messages_header(file): receiver = parser.parse(file) header_guard = messages_header_filename(receiver).replace('.', '_') result = [] result.append(_license_header) result.append('#ifndef %s\n' % header_guard) result.append('#define %s\n\n' % header_guard) if receiver.condition: result.append('#if %s\n\n' % receiver.condition) forward_declarations, headers = forward_declarations_and_headers(receiver) result += headers result.append('\n') result.append(forward_declarations) result.append('\n') result.append('namespace Messages {\nnamespace %s {\n' % receiver.name) result.append('\n') result.append('static inline IPC::StringReference messageReceiverName()\n') result.append('{\n') result.append(' return IPC::StringReference("%s");\n' % receiver.name) result.append('}\n') result.append('\n') result.append('\n'.join([message_to_struct_declaration(x) for x in receiver.messages])) result.append('\n') result.append('} // namespace %s\n} // namespace Messages\n' % receiver.name) if receiver.condition: result.append('\n#endif // %s\n' % receiver.condition) result.append('\n#endif // %s\n' % header_guard) return ''.join(result)
def generate_message_handler(file): receiver = parser.parse(file) header_conditions = { '"%s"' % messages_header_filename(receiver): [None], '"HandleMessage.h"': [None], '"Decoder.h"': [None], } type_conditions = {} for parameter in receiver.iterparameters(): if not parameter.type in type_conditions: type_conditions[parameter.type] = [] if not parameter.condition in type_conditions[parameter.type]: type_conditions[parameter.type].append(parameter.condition) for parameter in receiver.iterparameters(): type = parameter.type conditions = type_conditions[type] argument_encoder_headers = argument_coder_headers_for_type(type) if argument_encoder_headers: for header in argument_encoder_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].extend(conditions) type_headers = headers_for_type(type) for header in type_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].extend(conditions) for message in receiver.messages: if message.reply_parameters is not None: for reply_parameter in message.reply_parameters: type = reply_parameter.type argument_encoder_headers = argument_coder_headers_for_type(type) if argument_encoder_headers: for header in argument_encoder_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].append(message.condition) type_headers = headers_for_type(type) for header in type_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].append(message.condition) result = [] result.append(_license_header) result.append('#include "config.h"\n') result.append('\n') if receiver.condition: result.append('#if %s\n\n' % receiver.condition) result.append('#include "%s.h"\n\n' % receiver.name) for header in sorted(header_conditions): if header_conditions[header] and not None in header_conditions[header]: result.append('#if %s\n' % ' || '.join(set(header_conditions[header]))) result += ['#include %s\n' % header] result.append('#endif\n') else: result += ['#include %s\n' % header] result.append('\n') sync_delayed_messages = [] for message in receiver.messages: if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE): sync_delayed_messages.append(message) if sync_delayed_messages: result.append('namespace Messages {\n\nnamespace %s {\n\n' % receiver.name) for message in sync_delayed_messages: send_parameters = [(function_parameter_type(x.type), x.name) for x in message.reply_parameters] if message.condition: result.append('#if %s\n\n' % message.condition) result.append('%s::DelayedReply::DelayedReply(PassRefPtr<IPC::Connection> connection, std::unique_ptr<IPC::Encoder> encoder)\n' % message.name) result.append(' : m_connection(connection)\n') result.append(' , m_encoder(WTFMove(encoder))\n') result.append('{\n') result.append('}\n') result.append('\n') result.append('%s::DelayedReply::~DelayedReply()\n' % message.name) result.append('{\n') result.append(' ASSERT(!m_connection);\n') result.append('}\n') result.append('\n') result.append('bool %s::DelayedReply::send(%s)\n' % (message.name, ', '.join([' '.join(x) for x in send_parameters]))) result.append('{\n') result.append(' ASSERT(m_encoder);\n') result += [' *m_encoder << %s;\n' % x.name for x in message.reply_parameters] result.append(' bool _result = m_connection->sendSyncReply(WTFMove(m_encoder));\n') result.append(' m_connection = nullptr;\n') result.append(' return _result;\n') result.append('}\n') result.append('\n') if message.condition: result.append('#endif\n\n') result.append('} // namespace %s\n\n} // namespace Messages\n\n' % receiver.name) result.append('namespace WebKit {\n\n') async_messages = [] sync_messages = [] for message in receiver.messages: if message.reply_parameters is not None: sync_messages.append(message) else: async_messages.append(message) if async_messages: result.append('void %s::didReceive%sMessage(IPC::Connection& connection, IPC::Decoder& decoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else '')) result.append('{\n') result += [async_message_statement(receiver, message) for message in async_messages] if (receiver.superclass): result.append(' %s::didReceiveMessage(connection, decoder);\n' % (receiver.superclass)) else: result.append(' UNUSED_PARAM(connection);\n') result.append(' UNUSED_PARAM(decoder);\n') result.append(' ASSERT_NOT_REACHED();\n') result.append('}\n') if sync_messages: result.append('\n') result.append('void %s::didReceiveSync%sMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else '')) result.append('{\n') result += [sync_message_statement(receiver, message) for message in sync_messages] result.append(' UNUSED_PARAM(connection);\n') result.append(' UNUSED_PARAM(decoder);\n') result.append(' UNUSED_PARAM(replyEncoder);\n') result.append(' ASSERT_NOT_REACHED();\n') result.append('}\n') result.append('\n} // namespace WebKit\n') if receiver.condition: result.append('\n#endif // %s\n' % receiver.condition) return ''.join(result)
def generate_message_handler(file): receiver = parser.parse(file) header_conditions = { '"%s"' % messages_header_filename(receiver): [None], '"HandleMessage.h"': [None], '"MessageDecoder.h"': [None], } type_conditions = {} for parameter in receiver.iterparameters(): if not parameter.type in type_conditions: type_conditions[parameter.type] = [] if not parameter.condition in type_conditions[parameter.type]: type_conditions[parameter.type].append(parameter.condition) for parameter in receiver.iterparameters(): type = parameter.type conditions = type_conditions[type] argument_encoder_headers = argument_coder_headers_for_type(type) if argument_encoder_headers: for header in argument_encoder_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].extend(conditions) type_headers = headers_for_type(type) for header in type_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].extend(conditions) for message in receiver.messages: if message.reply_parameters is not None: for reply_parameter in message.reply_parameters: type = reply_parameter.type argument_encoder_headers = argument_coder_headers_for_type(type) if argument_encoder_headers: for header in argument_encoder_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].append(message.condition) type_headers = headers_for_type(type) for header in type_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].append(message.condition) result = [] result.append(_license_header) result.append('#include "config.h"\n') result.append('\n') if receiver.condition: result.append('#if %s\n\n' % receiver.condition) result.append('#include "%s.h"\n\n' % receiver.name) for header in sorted(header_conditions): if header_conditions[header] and not None in header_conditions[header]: result.append('#if %s\n' % ' || '.join(set(header_conditions[header]))) result += ['#include %s\n' % header] result.append('#endif\n') else: result += ['#include %s\n' % header] result.append('\n') sync_delayed_messages = [] for message in receiver.messages: if message.reply_parameters != None and message.has_attribute(DELAYED_ATTRIBUTE): sync_delayed_messages.append(message) if sync_delayed_messages: result.append('namespace Messages {\n\nnamespace %s {\n\n' % receiver.name) for message in sync_delayed_messages: send_parameters = [(function_parameter_type(x.type), x.name) for x in message.reply_parameters] if message.condition: result.append('#if %s\n\n' % message.condition) result.append('%s::DelayedReply::DelayedReply(PassRefPtr<IPC::Connection> connection, std::unique_ptr<IPC::MessageEncoder> encoder)\n' % message.name) result.append(' : m_connection(connection)\n') result.append(' , m_encoder(WTF::move(encoder))\n') result.append('{\n') result.append('}\n') result.append('\n') result.append('%s::DelayedReply::~DelayedReply()\n' % message.name) result.append('{\n') result.append(' ASSERT(!m_connection);\n') result.append('}\n') result.append('\n') result.append('bool %s::DelayedReply::send(%s)\n' % (message.name, ', '.join([' '.join(x) for x in send_parameters]))) result.append('{\n') result.append(' ASSERT(m_encoder);\n') result += [' *m_encoder << %s;\n' % x.name for x in message.reply_parameters] result.append(' bool _result = m_connection->sendSyncReply(WTF::move(m_encoder));\n') result.append(' m_connection = nullptr;\n') result.append(' return _result;\n') result.append('}\n') result.append('\n') if message.condition: result.append('#endif\n\n') result.append('} // namespace %s\n\n} // namespace Messages\n\n' % receiver.name) result.append('namespace WebKit {\n\n') async_messages = [] sync_messages = [] for message in receiver.messages: if message.reply_parameters is not None: sync_messages.append(message) else: async_messages.append(message) if async_messages: if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): result.append('void %s::didReceive%sMessage(IPC::Connection*, IPC::MessageDecoder& decoder)\n' % (receiver.name, receiver.name)) else: result.append('void %s::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)\n' % (receiver.name)) result.append('{\n') result += [async_message_statement(receiver, message) for message in async_messages] if (receiver.superclass): result.append(' %s::didReceiveMessage(connection, decoder);\n' % (receiver.superclass)) else: if not receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): result.append(' UNUSED_PARAM(connection);\n') result.append(' UNUSED_PARAM(decoder);\n') result.append(' ASSERT_NOT_REACHED();\n') result.append('}\n') if sync_messages: result.append('\n') use_connection = True if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE): if not sync_delayed_messages: use_connection = False 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 use_connection else '')) else: result.append('void %s::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)\n' % (receiver.name)) result.append('{\n') result += [sync_message_statement(receiver, message) for message in sync_messages] if use_connection: result.append(' UNUSED_PARAM(connection);\n') result.append(' UNUSED_PARAM(decoder);\n') result.append(' UNUSED_PARAM(replyEncoder);\n') result.append(' ASSERT_NOT_REACHED();\n') result.append('}\n') result.append('\n} // namespace WebKit\n') if receiver.condition: result.append('\n#endif // %s\n' % receiver.condition) return ''.join(result)
def generate_message_handler(file): receiver = parser.parse(file) header_conditions = { '"%s"' % messages_header_filename(receiver): [None], '"HandleMessage.h"': [None], '"Decoder.h"': [None], } type_conditions = {} for parameter in receiver.iterparameters(): if not parameter.type in type_conditions: type_conditions[parameter.type] = [] if not parameter.condition in type_conditions[parameter.type]: type_conditions[parameter.type].append(parameter.condition) for parameter in receiver.iterparameters(): type = parameter.type conditions = type_conditions[type] argument_encoder_headers = argument_coder_headers_for_type(type) if argument_encoder_headers: for header in argument_encoder_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].extend(conditions) type_headers = headers_for_type(type) for header in type_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].extend(conditions) for message in receiver.messages: if message.reply_parameters is not None: for reply_parameter in message.reply_parameters: type = reply_parameter.type argument_encoder_headers = argument_coder_headers_for_type(type) if argument_encoder_headers: for header in argument_encoder_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].append(message.condition) type_headers = headers_for_type(type) for header in type_headers: if header not in header_conditions: header_conditions[header] = [] header_conditions[header].append(message.condition) result = [] result.append(_license_header) result.append('#include "config.h"\n') result.append('\n') if receiver.condition: result.append('#if %s\n\n' % receiver.condition) result.append('#include "%s.h"\n\n' % receiver.name) for header in sorted(header_conditions): if header_conditions[header] and not None in header_conditions[header]: result.append('#if %s\n' % ' || '.join(set(header_conditions[header]))) result += ['#include %s\n' % header] result.append('#endif\n') else: result += ['#include %s\n' % header] result.append('\n') delayed_or_async_messages = [] for message in receiver.messages: if message.reply_parameters != None and (message.has_attribute(SYNCHRONOUS_ATTRIBUTE) or message.has_attribute(ASYNC_ATTRIBUTE)): delayed_or_async_messages.append(message) if delayed_or_async_messages: result.append('namespace Messages {\n\nnamespace %s {\n\n' % receiver.name) for message in delayed_or_async_messages: send_parameters = [(function_parameter_type(x.type, x.kind), x.name) for x in message.reply_parameters] if message.condition: result.append('#if %s\n\n' % message.condition) if message.has_attribute(ASYNC_ATTRIBUTE): move_parameters = message.name, ', '.join([move_type(x.type) for x in message.reply_parameters]) result.append('void %s::callReply(IPC::Decoder& decoder, CompletionHandler<void(%s)>&& completionHandler)\n{\n' % move_parameters) for x in message.reply_parameters: result.append(' Optional<%s> %s;\n' % (x.type, x.name)) result.append(' decoder >> %s;\n' % x.name) result.append(' if (!%s) {\n ASSERT_NOT_REACHED();\n cancelReply(WTFMove(completionHandler));\n return;\n }\n' % x.name) result.append(' completionHandler(') if len(message.reply_parameters): result.append('WTFMove(*%s)' % ('), WTFMove(*'.join(x.name for x in message.reply_parameters))) result.append(');\n}\n\n') result.append('void %s::cancelReply(CompletionHandler<void(%s)>&& completionHandler)\n{\n completionHandler(' % move_parameters) result.append(', '.join(['IPC::AsyncReplyError<' + x.type + '>::create()' for x in message.reply_parameters])) result.append(');\n}\n\n') result.append('void %s::send(std::unique_ptr<IPC::Encoder>&& encoder, IPC::Connection& connection' % (message.name)) if len(send_parameters): result.append(', %s' % ', '.join([' '.join(x) for x in send_parameters])) result.append(')\n{\n') result += [' *encoder << %s;\n' % x.name for x in message.reply_parameters] result.append(' connection.sendSyncReply(WTFMove(encoder));\n') result.append('}\n') result.append('\n') if message.condition: result.append('#endif\n\n') result.append('} // namespace %s\n\n} // namespace Messages\n\n' % receiver.name) result.append('namespace WebKit {\n\n') async_messages = [] sync_messages = [] for message in receiver.messages: if message.reply_parameters is not None and not message.has_attribute(ASYNC_ATTRIBUTE): sync_messages.append(message) else: async_messages.append(message) if async_messages: result.append('void %s::didReceive%sMessage(IPC::Connection& connection, IPC::Decoder& decoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else '')) result.append('{\n') result += [async_message_statement(receiver, message) for message in async_messages] if (receiver.superclass): result.append(' %s::didReceiveMessage(connection, decoder);\n' % (receiver.superclass)) else: result.append(' UNUSED_PARAM(connection);\n') result.append(' UNUSED_PARAM(decoder);\n') result.append(' ASSERT_NOT_REACHED();\n') result.append('}\n') if sync_messages: result.append('\n') result.append('void %s::didReceiveSync%sMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)\n' % (receiver.name, receiver.name if receiver.has_attribute(LEGACY_RECEIVER_ATTRIBUTE) else '')) result.append('{\n') result += [sync_message_statement(receiver, message) for message in sync_messages] result.append(' UNUSED_PARAM(connection);\n') result.append(' UNUSED_PARAM(decoder);\n') result.append(' UNUSED_PARAM(replyEncoder);\n') result.append(' ASSERT_NOT_REACHED();\n') result.append('}\n') result.append('\n} // namespace WebKit\n\n') if receiver.condition: result.append('\n#endif // %s\n' % receiver.condition) return ''.join(result)
def test_error_at_elif(self): with self.assertRaisesRegexp( Exception, r"ERROR: '#elif.*' is not supported in the \*\.in files"): parser.parse(StringIO("asd\n#elif bla\nfoo"))
def parse_receiver(receiver_name): with open( os.path.join(tests_directory, '{}.messages.in'.format(receiver_name))) as in_file: return parser.parse(in_file) assert (False)
def setUp(self): self.receiver = parser.parse(StringIO(_messages_file_contents)) self.legacy_receiver = parser.parse(StringIO(_legacy_messages_file_contents)) self.superclass_receiver = parser.parse(StringIO(_superclass_messages_file_contents))
def test_error_at_else(self): with self.assertRaisesRegexp( Exception, r"ERROR: '#else.*' is not supported in the \*\.in files"): messages.generate_message_handler( parser.parse(StringIO("asd\n#else bla\nfoo")))
def assertImplementationEqual(self, input_messages_file_contents, expected_file_name): actual_file_contents = messages.generate_message_handler( parser.parse(StringIO(input_messages_file_contents))) self.assertGeneratedFileContentsEqual(actual_file_contents, expected_file_name)
def assertHeaderEqual(self, input_messages_file_contents, expected_file_name): actual_file_contents = messages.generate_messages_header( parser.parse(StringIO(input_messages_file_contents))) self.assertGeneratedFileContentsEqual(actual_file_contents, expected_file_name)