Web Inspector: make ObjC protocol dispatcher commands optional and add `respondsToSelector` checks to allow other inspector clients to choose what they implement
https://bugs.webkit.org/show_bug.cgi?id=203197

Reviewed by Joseph Pecoraro.

This will help eliminate internal build failures, and will also allow other clients to
remove all of their commands that previously just responded with an "unsupported" error.

* inspector/scripts/codegen/objc_generator_templates.py:
* inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
(ObjCBackendDispatcherImplementationGenerator._generate_handler_implementation_for_command):
(ObjCBackendDispatcherImplementationGenerator._generate_responds_to_selector_for_command): Added.
Add a `respondsToSelector` check before attempting to call the delegate function.

* inspector/scripts/codegen/generate_objc_header.py:
(ObjCHeaderGenerator._generate_command_protocols):
Mark all commands as `@optional`.

* inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result:
* inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result:
* inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result:
* inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result:
* inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result:
* inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result:
* inspector/scripts/tests/generic/expected/domain-targetTypes.json-result:
* inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result:
* inspector/scripts/tests/generic/expected/enum-values.json-result:
* inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result:
* inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result:
* inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251395 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 2ce0dfd..173b6c3 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,36 @@
+2019-10-21  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: make ObjC protocol dispatcher commands optional and add `respondsToSelector` checks to allow other inspector clients to choose what they implement
+        https://bugs.webkit.org/show_bug.cgi?id=203197
+
+        Reviewed by Joseph Pecoraro.
+
+        This will help eliminate internal build failures, and will also allow other clients to
+        remove all of their commands that previously just responded with an "unsupported" error.
+
+        * inspector/scripts/codegen/objc_generator_templates.py:
+        * inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py:
+        (ObjCBackendDispatcherImplementationGenerator._generate_handler_implementation_for_command):
+        (ObjCBackendDispatcherImplementationGenerator._generate_responds_to_selector_for_command): Added.
+        Add a `respondsToSelector` check before attempting to call the delegate function.
+
+        * inspector/scripts/codegen/generate_objc_header.py:
+        (ObjCHeaderGenerator._generate_command_protocols):
+        Mark all commands as `@optional`.
+
+        * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result:
+        * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result:
+        * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result:
+        * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result:
+        * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result:
+        * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result:
+        * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result:
+        * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result:
+        * inspector/scripts/tests/generic/expected/enum-values.json-result:
+        * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result:
+        * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result:
+        * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result:
+
 2019-10-21  Saam Barati  <sbarati@apple.com>
 
         JSON.parse has bad is array assert
diff --git a/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py b/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py
index 90626a0..a1b9e17 100755
--- a/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py
+++ b/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_backend_dispatcher_implementation.py
@@ -98,6 +98,7 @@
             'domainName': domain.domain_name,
             'commandName': command.command_name,
             'parameters': ', '.join(parameters),
+            'respondsToSelector': self._generate_responds_to_selector_for_command(domain, command),
             'successCallback': self._generate_success_block_for_command(domain, command),
             'conversions': self._generate_conversions_for_command(domain, command),
             'invocation': self._generate_invocation_for_command(domain, command),
@@ -105,6 +106,9 @@
 
         return self.wrap_with_guard_for_domain(domain, Template(ObjCTemplates.BackendDispatcherHeaderDomainHandlerImplementation).substitute(None, **command_args))
 
+    def _generate_responds_to_selector_for_command(self, domain, command):
+        return '[m_delegate respondsToSelector:@selector(%sWithErrorCallback:successCallback:%s)]' % (command.command_name, ''.join(map(lambda parameter: '%s:' % parameter.parameter_name, command.call_parameters)))
+
     def _generate_success_block_for_command(self, domain, command):
         lines = []
 
diff --git a/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_header.py b/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_header.py
index fc0cc2a..15fb74b 100755
--- a/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_header.py
+++ b/Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_header.py
@@ -215,7 +215,7 @@
         if self.commands_for_domain(domain):
             objc_name = '%s%sDomainHandler' % (self.objc_prefix(), domain.domain_name)
             lines.append('@protocol %s <NSObject>' % objc_name)
-            lines.append('@required')
+            lines.append('@optional')
             for command in self.commands_for_domain(domain):
                 lines.append(self._generate_single_command_protocol(domain, command))
             lines.append('@end')
diff --git a/Source/JavaScriptCore/inspector/scripts/codegen/objc_generator_templates.py b/Source/JavaScriptCore/inspector/scripts/codegen/objc_generator_templates.py
index cc2b566..2274215 100755
--- a/Source/JavaScriptCore/inspector/scripts/codegen/objc_generator_templates.py
+++ b/Source/JavaScriptCore/inspector/scripts/codegen/objc_generator_templates.py
@@ -113,6 +113,12 @@
     BackendDispatcherHeaderDomainHandlerImplementation = (
     """void ObjCInspector${domainName}BackendDispatcher::${commandName}(${parameters})
 {
+    if (!${respondsToSelector}) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'${domainName}.${commandName}' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result b/Source/JavaScriptCore/inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result
index 4977786..9b3cee6 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result
@@ -640,6 +640,12 @@
 
 void ObjCInspectorNetworkBackendDispatcher::loadResource(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResourceWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network.loadResource' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -920,7 +926,7 @@
 @end
 
 @protocol TestProtocolNetworkDomainHandler <NSObject>
-@required
+@optional
 - (void)loadResourceWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result
index e98df71..485aa61 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result
@@ -567,6 +567,12 @@
 
 void ObjCInspectorDomainBackendDispatcher::Command(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(CommandWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Domain.Command' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -839,7 +845,7 @@
 
 
 @protocol TestProtocolDomainDomainHandler <NSObject>
-@required
+@optional
 - (void)CommandWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result
index f310fd6..59b3e3c 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result
@@ -919,6 +919,12 @@
 
 void ObjCInspectorDatabaseBackendDispatcher::executeSQLSyncOptionalReturnValues(long requestId, int in_databaseId, const String& in_query)
 {
+    if (![m_delegate respondsToSelector:@selector(executeSQLSyncOptionalReturnValuesWithErrorCallback:successCallback:databaseId:query:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Database.executeSQLSyncOptionalReturnValues' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -963,6 +969,12 @@
 
 void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsyncOptionalReturnValues(long requestId, int in_databaseId, const String& in_query)
 {
+    if (![m_delegate respondsToSelector:@selector(executeSQLAsyncOptionalReturnValuesWithErrorCallback:successCallback:databaseId:query:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Database.executeSQLAsyncOptionalReturnValues' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -1007,6 +1019,12 @@
 
 void ObjCInspectorDatabaseBackendDispatcher::executeSQLSync(long requestId, int in_databaseId, const String& in_query)
 {
+    if (![m_delegate respondsToSelector:@selector(executeSQLSyncWithErrorCallback:successCallback:databaseId:query:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Database.executeSQLSync' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -1041,6 +1059,12 @@
 
 void ObjCInspectorDatabaseBackendDispatcher::executeSQLAsync(long requestId, int in_databaseId, const String& in_query)
 {
+    if (![m_delegate respondsToSelector:@selector(executeSQLAsyncWithErrorCallback:successCallback:databaseId:query:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Database.executeSQLAsync' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -1338,7 +1362,7 @@
 @end
 
 @protocol TestProtocolDatabaseDomainHandler <NSObject>
-@required
+@optional
 - (void)executeSQLSyncOptionalReturnValuesWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, TestProtocolDatabaseError **sqlError, TestProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, TestProtocolDatabaseExecuteSQLSyncOptionalReturnValuesPrintColor *printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
 - (void)executeSQLAsyncOptionalReturnValuesWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, TestProtocolDatabaseError **sqlError, TestProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, TestProtocolDatabaseExecuteSQLAsyncOptionalReturnValuesPrintColor *printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
 - (void)executeSQLSyncWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, TestProtocolDatabaseError *sqlError, NSArray/*<NSString>*/ *alternateColors, TestProtocolDatabasePrimaryColors screenColor, TestProtocolDatabaseExecuteSQLSyncPrintColor printColor))successCallback databaseId:(int)databaseId query:(NSString *)query;
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result
index ade8c5f..9db56b5 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result
@@ -832,6 +832,12 @@
 
 void ObjCInspectorDatabaseBackendDispatcher::executeAllOptionalParameters(long requestId, const JSON::Array* in_columnNames, const String* in_notes, const double* in_timestamp, const JSON::Object* in_values, const JSON::Value* in_payload, const int* in_databaseId, const JSON::Object* in_sqlError, const String* in_screenColor, const JSON::Array* in_alternateColors, const String* in_printColor)
 {
+    if (![m_delegate respondsToSelector:@selector(executeAllOptionalParametersWithErrorCallback:successCallback:columnNames:notes:timestamp:values:payload:databaseId:sqlError:screenColor:alternateColors:printColor:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Database.executeAllOptionalParameters' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -904,6 +910,12 @@
 
 void ObjCInspectorDatabaseBackendDispatcher::executeNoOptionalParameters(long requestId, const JSON::Array& in_columnNames, const String& in_notes, double in_timestamp, const JSON::Object& in_values, JSON::Value in_payload, int in_databaseId, const JSON::Object& in_sqlError, const String& in_screenColor, const JSON::Array& in_alternateColors, const String& in_printColor)
 {
+    if (![m_delegate respondsToSelector:@selector(executeNoOptionalParametersWithErrorCallback:successCallback:columnNames:notes:timestamp:values:payload:databaseId:sqlError:screenColor:alternateColors:printColor:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Database.executeNoOptionalParameters' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -1217,7 +1229,7 @@
 @end
 
 @protocol TestProtocolDatabaseDomainHandler <NSObject>
-@required
+@optional
 - (void)executeAllOptionalParametersWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ **columnNames, NSString **notes, double *timestamp, RWIProtocolJSONObject **values, RWIProtocolJSONObject **payload, int *databaseId, TestProtocolDatabaseError **sqlError, TestProtocolDatabasePrimaryColors *screenColor, NSArray/*<NSString>*/ **alternateColors, TestProtocolDatabaseExecuteAllOptionalParametersPrintColor *printColor))successCallback columnNames:(NSArray/*<NSString>*/ **)columnNames notes:(NSString **)notes timestamp:(double *)timestamp values:(RWIProtocolJSONObject **)values payload:(RWIProtocolJSONObject **)payload databaseId:(int *)databaseId sqlError:(TestProtocolDatabaseError **)sqlError screenColor:(TestProtocolDatabasePrimaryColors *)screenColor alternateColors:(NSArray/*<NSString>*/ **)alternateColors printColor:(TestProtocolDatabaseExecuteAllOptionalParametersPrintColor *)printColor;
 - (void)executeNoOptionalParametersWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(NSArray/*<NSString>*/ *columnNames, NSString *notes, double timestamp, RWIProtocolJSONObject *values, RWIProtocolJSONObject *payload, int databaseId, TestProtocolDatabaseError *sqlError, TestProtocolDatabasePrimaryColors screenColor, NSArray/*<NSString>*/ *alternateColors, TestProtocolDatabaseExecuteNoOptionalParametersPrintColor printColor))successCallback columnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload databaseId:(int)databaseId sqlError:(TestProtocolDatabaseError *)sqlError screenColor:(TestProtocolDatabasePrimaryColors)screenColor alternateColors:(NSArray/*<NSString>*/ *)alternateColors printColor:(TestProtocolDatabaseExecuteNoOptionalParametersPrintColor)printColor;
 @end
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result
index 6872950..3d65b04 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result
@@ -567,6 +567,12 @@
 
 void ObjCInspectorDomainBackendDispatcher::Command(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(CommandWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Domain.Command' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -839,7 +845,7 @@
 
 
 @protocol TestProtocolDomainDomainHandler <NSObject>
-@required
+@optional
 - (void)CommandWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result
index 8e2d7fd..cc08ae9 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result
@@ -567,6 +567,12 @@
 
 void ObjCInspectorDomainBackendDispatcher::Command(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(CommandWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Domain.Command' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -839,7 +845,7 @@
 
 
 @protocol TestProtocolDomainDomainHandler <NSObject>
-@required
+@optional
 - (void)CommandWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetTypes.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetTypes.json-result
index 7bc8567..ae8f093e 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetTypes.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domain-targetTypes.json-result
@@ -567,6 +567,12 @@
 
 void ObjCInspectorDomainBackendDispatcher::Command(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(CommandWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Domain.Command' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -839,7 +845,7 @@
 
 
 @protocol TestProtocolDomainDomainHandler <NSObject>
-@required
+@optional
 - (void)CommandWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result
index aa6eda0..3b907c7 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result
@@ -811,6 +811,12 @@
 
 void ObjCInspectorNetwork1BackendDispatcher::loadResource1(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource1WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network1.loadResource1' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -826,6 +832,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource1(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource1WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource1' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -840,6 +852,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource2(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource2WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource2' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -854,6 +872,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource3(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource3WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource3' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -868,6 +892,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource4(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource4WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource4' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -882,6 +912,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource5(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource5WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource5' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -896,6 +932,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource6(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource6WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource6' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -910,6 +952,12 @@
 
 void ObjCInspectorNetwork3BackendDispatcher::loadResource7(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResource7WithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network3.loadResource7' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -1167,12 +1215,12 @@
 
 
 @protocol TestProtocolNetwork1DomainHandler <NSObject>
-@required
+@optional
 - (void)loadResource1WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
 @protocol TestProtocolNetwork3DomainHandler <NSObject>
-@required
+@optional
 - (void)loadResource1WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 - (void)loadResource2WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 - (void)loadResource3WithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/enum-values.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/enum-values.json-result
index 40a51d8..59757bb 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/enum-values.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/enum-values.json-result
@@ -684,6 +684,12 @@
 
 void ObjCInspectorCommandDomainBackendDispatcher::commandWithEnumReturnValue(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(commandWithEnumReturnValueWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'CommandDomain.commandWithEnumReturnValue' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -967,7 +973,7 @@
 
 
 @protocol TestProtocolCommandDomainDomainHandler <NSObject>
-@required
+@optional
 - (void)commandWithEnumReturnValueWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(TestProtocolCommandDomainCommandWithEnumReturnValueReturnValue returnValue))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result
index 045e164..3944f48 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result
@@ -567,6 +567,12 @@
 
 void ObjCInspectorDomainBackendDispatcher::Command(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(CommandWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Domain.Command' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -839,7 +845,7 @@
 
 
 @protocol TestProtocolDomainDomainHandler <NSObject>
-@required
+@optional
 - (void)CommandWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result
index 78e7f6e..1bda712 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result
@@ -667,6 +667,12 @@
 #if PLATFORM(WEB_COMMANDS)
 void ObjCInspectorNetwork1BackendDispatcher::loadResource(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResourceWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network1.loadResource' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -948,7 +954,7 @@
 @end
 
 @protocol TestProtocolNetwork1DomainHandler <NSObject>
-@required
+@optional
 - (void)loadResourceWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end
 
diff --git a/Source/JavaScriptCore/inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result b/Source/JavaScriptCore/inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result
index 4977786..9b3cee6 100644
--- a/Source/JavaScriptCore/inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result
+++ b/Source/JavaScriptCore/inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result
@@ -640,6 +640,12 @@
 
 void ObjCInspectorNetworkBackendDispatcher::loadResource(long requestId)
 {
+    if (![m_delegate respondsToSelector:@selector(loadResourceWithErrorCallback:successCallback:)]) {
+        backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::MethodNotFound, "'Network.loadResource' was not found"_s);
+        backendDispatcher()->sendPendingErrors();
+        return;
+    }
+
     id errorCallback = ^(NSString *error) {
         backendDispatcher()->reportProtocolError(requestId, BackendDispatcher::ServerError, error);
         backendDispatcher()->sendPendingErrors();
@@ -920,7 +926,7 @@
 @end
 
 @protocol TestProtocolNetworkDomainHandler <NSObject>
-@required
+@optional
 - (void)loadResourceWithErrorCallback:(void(^)(NSString *error))errorCallback successCallback:(void(^)(void))successCallback;
 @end