From a13826d72b83913ba242b6b92662f92ca98f5e5e Mon Sep 17 00:00:00 2001 From: Autopilot Bot Date: Fri, 23 Oct 2026 06:20:26 -0700 Subject: [PATCH] Add explicit nullability annotations to `RCTBridgeModule.h` Summary: `RCTBridgeModule.h` had no nullability annotations at all, so `viewRegistry_DEPRECATED` and the other module properties had no explicit nullability qualifier. Once a header has any nullability specifier, clang's `-Wnullability-completeness` requires every pointer in it to be annotated. So this wraps the header in `NS_ASSUME_NONNULL_BEGIN/END` and marks as `nullable` only the pointers that the implementations and callers show can actually be nil: - Weak module properties (`moduleRegistry`, `viewRegistry_DEPRECATED`, `bundleManager`, `callableJSModules`, `bridge`) are `nullable`, because a weak reference can become nil. - `RCTPromiseResolveBlock`'s `result` is `nullable`: the header comment already says nil resolves to `undefined`, and modules call `resolve(nil)`. - All three `RCTPromiseRejectBlock` parameters are `nullable`. `RCTJSErrorFromCodeMessageAndNSError` substitutes defaults for a nil code or message, and modules call `reject(nil, nil, error)`. - `RCTResponseSenderBlock`'s `response` is `nullable`, because the TurboModule callback converts a nil array into a call with no arguments. `RCTResponseErrorBlock`'s `error` is nonnull, because it exists to report an error. - `methodsToExport` returns `nullable`, because callers fall back when they get nil, and nothing in fbsource implements it. - `constantsToExport` is nonnull. Typed implementations return `ModuleConstants<...>` inside `NS_ASSUME_NONNULL` regions, Expo's `EXNativeModulesProxy` declares it `nonnull`, and `RCTTypedModuleConstants.h` documents it as `nonnull`. A `nullable` declaration is a hard "nullability specifier 'nonnull' conflicts with existing specifier 'nullable'" error in those implementations. No implementation in fbsource declares it `nullable`. - `+moduleName` has no nullability specifier. It sits in a small `#pragma clang assume_nonnull end/begin` gap, with `-Wnullability-completeness` suppressed. `RCT_EXPORT_MODULE` expansions inside `NS_ASSUME_NONNULL` files are implicitly nonnull, but Expo's `EXModuleRegistryHolderReactModule` declares `+ (nullable NSString *)moduleName` and returns nil. So `nonnull`, `nullable`, and `null_unspecified` would each conflict with one of them. `RCTBridgeModuleNameForClass` already handles a nil or empty name. - `RCTModuleRegistry` `moduleForName:` / `moduleForName:lazilyLoadIfNecessary:` / `moduleForClass:` return `nullable`, because they return nil when no TurboModule registry is set or the module isn't found. The `const char *moduleName` argument stays nonnull: a module lookup needs a name. - `methodQueue` is nonnull. An override exists to return a queue. Any explicit specifier other than `nonnull` (including `null_unspecified`) is a hard error ("nullability specifier 'nonnull' conflicts with existing specifier") for Objective-C overrides inside `NS_ASSUME_NONNULL` regions, such as Twilight's `TWMHEConfigurationTurboModule`. - `RCTViewRegistry` `viewForReactTag:` returns `nullable`, because the bridgeless provider returns nil once the surface presenter is gone, and `RCTBridgelessComponentViewProvider`'s return type is `nullable` to match. `addUIBlock:` takes a `nullable` block, because the implementation returns early on nil. - The `args` and `onComplete` parameters of `RCTCallableJSModules invokeModule:...` and `RCTBridgelessJSModuleMethodInvoker` are `nullable`. The 3-argument overload forwards `NULL` for `onComplete`, and the invoker substitutes `@[]` when `args` is nil. - Everything else (module/method names, tags, setters, `RCTMethodInfo` names, which always come from string literals) is nonnull through `NS_ASSUME_NONNULL`. There is no `null_unspecified`. The macro bodies (`RCT_EXPORT_MODULE`, `_RCT_EXTERN_REMAP_METHOD`, ...) expand in implementation files outside the audited region, so they are unaffected. Changelog: [iOS][Changed] - Add nullability annotations to `RCTBridgeModule.h`. Module registry and view registry lookups, `methodsToExport`, promise resolve/reject arguments, and weak module properties such as `bridge` and `moduleRegistry` are now `nullable`. `methodQueue` is now nonnull, so Swift overrides must be declared as `DispatchQueue` rather than `DispatchQueue!`. Reviewed By: christophpurrer, javache Differential Revision: D126391299 --- .../react-native/React/Base/RCTBridgeModule.h | 52 ++++++++++++------- .../api-snapshots/ReactAppleDebugCxx.api | 16 +++--- .../api-snapshots/ReactAppleFrameworksCxx.api | 16 +++--- .../api-snapshots/ReactAppleNewarchCxx.api | 16 +++--- .../api-snapshots/ReactAppleReleaseCxx.api | 16 +++--- 5 files changed, 64 insertions(+), 52 deletions(-) diff --git a/packages/react-native/React/Base/RCTBridgeModule.h b/packages/react-native/React/Base/RCTBridgeModule.h index 9fc86cdeed25..005e10d84f69 100644 --- a/packages/react-native/React/Base/RCTBridgeModule.h +++ b/packages/react-native/React/Base/RCTBridgeModule.h @@ -24,11 +24,13 @@ @class RCTCallableJSModules; @class RCTPerformanceLogger; +NS_ASSUME_NONNULL_BEGIN + /** * The type of a block that is capable of sending a response to a bridged * operation. Use this for returning callback methods to JS. */ -typedef void (^RCTResponseSenderBlock)(NSArray *response); +typedef void (^RCTResponseSenderBlock)(NSArray *_Nullable response); /** * The type of a block that is capable of sending an error response to a @@ -40,14 +42,14 @@ typedef void (^RCTResponseErrorBlock)(NSError *error); * Block that bridge modules use to resolve the JS promise waiting for a result. * Nil results are supported and are converted to JS's undefined value. */ -typedef void (^RCTPromiseResolveBlock)(id result); +typedef void (^RCTPromiseResolveBlock)(id _Nullable result); /** * Block that bridge modules use to reject the JS promise waiting for a result. * The error may be nil but it is preferable to pass an NSError object for more * precise error messages. */ -typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error); +typedef void (^RCTPromiseRejectBlock)(NSString *_Nullable code, NSString *_Nullable message, NSError *_Nullable error); RCT_EXTERN_C_BEGIN @@ -127,7 +129,15 @@ RCT_EXTERN_C_END // Implemented by RCT_EXPORT_MODULE. When absent, callers fall back to the ObjC class // name, so a TurboModule resolved via a provider or plugin socket need not declare it. +// Deliberately left without nullability: implementations inside NS_ASSUME_NONNULL regions +// are implicitly nonnull while others (e.g. Expo's EXModuleRegistryHolderReactModule) are +// explicitly nullable, and either specifier here would conflict with one of them. +#pragma clang assume_nonnull end +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + (NSString *)moduleName; +#pragma clang diagnostic pop +#pragma clang assume_nonnull begin /** * A reference to the RCTModuleRegistry. Useful for modules that require access @@ -135,7 +145,7 @@ RCT_EXTERN_C_END * moduleRegistry = _moduleRegistry;`. If using Swift, add * `@objc var moduleRegistry: RCTModuleRegistry!` to your module. */ -@property (nonatomic, weak, readwrite) RCTModuleRegistry *moduleRegistry; +@property (nonatomic, weak, nullable, readwrite) RCTModuleRegistry *moduleRegistry; /** * A reference to the RCTViewRegistry. Useful for modules that query UIViews, @@ -146,7 +156,7 @@ RCT_EXTERN_C_END * viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;`. If using Swift, add * `@objc var viewRegistry_DEPRECATED: RCTViewRegistry!` to your module. */ -@property (nonatomic, weak, readwrite) RCTViewRegistry *viewRegistry_DEPRECATED; +@property (nonatomic, weak, nullable, readwrite) RCTViewRegistry *viewRegistry_DEPRECATED; /** * A reference to the RCTBundleManager. Useful for modules that need to read @@ -156,7 +166,7 @@ RCT_EXTERN_C_END * _bundleManager;`. If using Swift, add `@objc var bundleManager: * RCTBundleManager!` to your module. */ -@property (nonatomic, weak, readwrite) RCTBundleManager *bundleManager; +@property (nonatomic, weak, nullable, readwrite) RCTBundleManager *bundleManager; /** * A reference to an RCTCallableJSModules. Useful for modules that need to @@ -167,7 +177,7 @@ RCT_EXTERN_C_END * _callableJSModules;`. If using Swift, add `@objc var callableJSModules: * RCTCallableJSModules!` to your module. */ -@property (nonatomic, weak, readwrite) RCTCallableJSModules *callableJSModules; +@property (nonatomic, weak, nullable, readwrite) RCTCallableJSModules *callableJSModules; /** * The launch options that were used to initialize the React instance. @@ -195,7 +205,7 @@ RCT_EXTERN_C_END * To implement this in your module, just add `@synthesize bridge = _bridge;` * If using Swift, add `@objc var bridge: RCTBridge!` to your module. */ -@property (nonatomic, weak, readonly) RCTBridge *bridge RCT_DEPRECATED; +@property (nonatomic, weak, nullable, readonly) RCTBridge *bridge RCT_DEPRECATED; /** * This property is deprecated. This selector used to support two functionalities. @@ -379,7 +389,7 @@ RCT_EXTERN_C_END * methods defined using the macros above. This method is called only once, * before registration. */ -- (NSArray> *)methodsToExport; +- (nullable NSArray> *)methodsToExport; /** * Injects constants into JS. These constants are made accessible via NativeModules.ModuleName.X. It is only called once @@ -405,15 +415,15 @@ RCT_EXTERN_C_END @interface RCTModuleRegistry : NSObject - (void)setTurboModuleRegistry:(id)turboModuleRegistry; -- (id)moduleForName:(const char *)moduleName; -- (id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad; +- (nullable id)moduleForName:(const char *)moduleName; +- (nullable id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad; - (BOOL)moduleIsInitialized:(Class)moduleClass; // Note: This method lazily load the module as necessary. -- (id)moduleForClass:(Class)moduleClass; +- (nullable id)moduleForClass:(Class)moduleClass; @end -typedef UIView * (^RCTBridgelessComponentViewProvider)(NSNumber *); +typedef UIView *_Nullable (^RCTBridgelessComponentViewProvider)(NSNumber *); typedef void (^RCTViewRegistryUIBlock)(RCTViewRegistry *viewRegistry); @@ -423,15 +433,15 @@ typedef void (^RCTViewRegistryUIBlock)(RCTViewRegistry *viewRegistry); @interface RCTViewRegistry : NSObject - (void)setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider)bridgelessComponentViewProvider; -- (UIView *)viewForReactTag:(NSNumber *)reactTag; -- (void)addUIBlock:(RCTViewRegistryUIBlock)block; +- (nullable UIView *)viewForReactTag:(NSNumber *)reactTag; +- (void)addUIBlock:(nullable RCTViewRegistryUIBlock)block; @end typedef void (^RCTBridgelessJSModuleMethodInvoker)( NSString *moduleName, NSString *methodName, - NSArray *args, - dispatch_block_t onComplete); + NSArray *_Nullable args, + dispatch_block_t _Nullable onComplete); /** * A class that allows NativeModules to call methods on JavaScript modules registered @@ -440,9 +450,11 @@ typedef void (^RCTBridgelessJSModuleMethodInvoker)( @interface RCTCallableJSModules : NSObject - (void)setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker; -- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args; +- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(nullable NSArray *)args; - (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName - withArgs:(NSArray *)args - onComplete:(dispatch_block_t)onComplete; + withArgs:(nullable NSArray *)args + onComplete:(nullable dispatch_block_t)onComplete; @end + +NS_ASSUME_NONNULL_END diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 863038207ad0..4d79037f4954 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -785,8 +785,8 @@ interface RCTCallInvoker : public NSObject { } interface RCTCallableJSModules : public NSObject { - public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, NSArray* args); - public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, NSArray* args, dispatch_block_t onComplete); + public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args); + public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args, _Nullable dispatch_block_t onComplete); public virtual void setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker bridgelessJSModuleMethodInvoker); } @@ -1382,9 +1382,9 @@ interface RCTModuleProviders : public NSObject { interface RCTModuleRegistry : public NSObject { public virtual BOOL moduleIsInitialized:(Class moduleClass); - public virtual id moduleForClass:(Class moduleClass); - public virtual id moduleForName:(const char* moduleName); - public virtual id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); + public virtual _Nullable id moduleForClass:(Class moduleClass); + public virtual _Nullable id moduleForName:(const char* moduleName); + public virtual _Nullable id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); public virtual void setTurboModuleRegistry:(id turboModuleRegistry); } @@ -2099,8 +2099,8 @@ interface RCTViewManager : public NSObject { } interface RCTViewRegistry : public NSObject { - public virtual UIView* viewForReactTag:(NSNumber* reactTag); - public virtual void addUIBlock:(RCTViewRegistryUIBlock block); + public virtual _Nullable UIView* viewForReactTag:(NSNumber* reactTag); + public virtual void addUIBlock:(_Nullable RCTViewRegistryUIBlock block); public virtual void setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider bridgelessComponentViewProvider); } @@ -2563,8 +2563,8 @@ protocol RCTBridgeModule : public NSObject { public @property (weak) RCTCallableJSModules* callableJSModules; public @property (weak) RCTModuleRegistry* moduleRegistry; public @property (weak, readonly) RCTBridge* bridge; - public virtual NSArray>* methodsToExport(); public virtual NSDictionary* constantsToExport(); + public virtual _Nullable NSArray>* methodsToExport(); public virtual static BOOL requiresMainQueueSetup(); public virtual static NSString* moduleName(); public virtual void batchDidComplete(); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index dece37c06a37..e4475a7bf2e5 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -794,8 +794,8 @@ interface RCTCallInvoker : public NSObject { } interface RCTCallableJSModules : public NSObject { - public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, NSArray* args); - public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, NSArray* args, dispatch_block_t onComplete); + public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args); + public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args, _Nullable dispatch_block_t onComplete); public virtual void setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker bridgelessJSModuleMethodInvoker); } @@ -1425,9 +1425,9 @@ interface RCTModuleProviders : public NSObject { interface RCTModuleRegistry : public NSObject { public virtual BOOL moduleIsInitialized:(Class moduleClass); - public virtual id moduleForClass:(Class moduleClass); - public virtual id moduleForName:(const char* moduleName); - public virtual id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); + public virtual _Nullable id moduleForClass:(Class moduleClass); + public virtual _Nullable id moduleForName:(const char* moduleName); + public virtual _Nullable id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); public virtual void setTurboModuleRegistry:(id turboModuleRegistry); } @@ -2157,8 +2157,8 @@ interface RCTViewManager : public NSObject { } interface RCTViewRegistry : public NSObject { - public virtual UIView* viewForReactTag:(NSNumber* reactTag); - public virtual void addUIBlock:(RCTViewRegistryUIBlock block); + public virtual _Nullable UIView* viewForReactTag:(NSNumber* reactTag); + public virtual void addUIBlock:(_Nullable RCTViewRegistryUIBlock block); public virtual void setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider bridgelessComponentViewProvider); } @@ -2621,8 +2621,8 @@ protocol RCTBridgeModule : public NSObject { public @property (weak) RCTCallableJSModules* callableJSModules; public @property (weak) RCTModuleRegistry* moduleRegistry; public @property (weak, readonly) RCTBridge* bridge; - public virtual NSArray>* methodsToExport(); public virtual NSDictionary* constantsToExport(); + public virtual _Nullable NSArray>* methodsToExport(); public virtual static BOOL requiresMainQueueSetup(); public virtual static NSString* moduleName(); public virtual void batchDidComplete(); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index 3e9a7b4744fc..22f9d5724fa9 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -785,8 +785,8 @@ interface RCTCallInvoker : public NSObject { } interface RCTCallableJSModules : public NSObject { - public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, NSArray* args); - public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, NSArray* args, dispatch_block_t onComplete); + public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args); + public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args, _Nullable dispatch_block_t onComplete); public virtual void setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker bridgelessJSModuleMethodInvoker); } @@ -1382,9 +1382,9 @@ interface RCTModuleProviders : public NSObject { interface RCTModuleRegistry : public NSObject { public virtual BOOL moduleIsInitialized:(Class moduleClass); - public virtual id moduleForClass:(Class moduleClass); - public virtual id moduleForName:(const char* moduleName); - public virtual id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); + public virtual _Nullable id moduleForClass:(Class moduleClass); + public virtual _Nullable id moduleForName:(const char* moduleName); + public virtual _Nullable id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); public virtual void setTurboModuleRegistry:(id turboModuleRegistry); } @@ -2092,8 +2092,8 @@ interface RCTViewManager : public NSObject { } interface RCTViewRegistry : public NSObject { - public virtual UIView* viewForReactTag:(NSNumber* reactTag); - public virtual void addUIBlock:(RCTViewRegistryUIBlock block); + public virtual _Nullable UIView* viewForReactTag:(NSNumber* reactTag); + public virtual void addUIBlock:(_Nullable RCTViewRegistryUIBlock block); public virtual void setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider bridgelessComponentViewProvider); } @@ -2555,8 +2555,8 @@ protocol RCTBridgeModule : public NSObject { public @property (weak) RCTCallableJSModules* callableJSModules; public @property (weak) RCTModuleRegistry* moduleRegistry; public @property (weak, readonly) RCTBridge* bridge; - public virtual NSArray>* methodsToExport(); public virtual NSDictionary* constantsToExport(); + public virtual _Nullable NSArray>* methodsToExport(); public virtual static BOOL requiresMainQueueSetup(); public virtual static NSString* moduleName(); public virtual void batchDidComplete(); diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index a692b6489f17..f4d22e70ea68 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -785,8 +785,8 @@ interface RCTCallInvoker : public NSObject { } interface RCTCallableJSModules : public NSObject { - public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, NSArray* args); - public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, NSArray* args, dispatch_block_t onComplete); + public virtual void invokeModule:method:withArgs:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args); + public virtual void invokeModule:method:withArgs:onComplete:(NSString* moduleName, NSString* methodName, _Nullable NSArray* args, _Nullable dispatch_block_t onComplete); public virtual void setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker bridgelessJSModuleMethodInvoker); } @@ -1382,9 +1382,9 @@ interface RCTModuleProviders : public NSObject { interface RCTModuleRegistry : public NSObject { public virtual BOOL moduleIsInitialized:(Class moduleClass); - public virtual id moduleForClass:(Class moduleClass); - public virtual id moduleForName:(const char* moduleName); - public virtual id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); + public virtual _Nullable id moduleForClass:(Class moduleClass); + public virtual _Nullable id moduleForName:(const char* moduleName); + public virtual _Nullable id moduleForName:lazilyLoadIfNecessary:(const char* moduleName, BOOL lazilyLoad); public virtual void setTurboModuleRegistry:(id turboModuleRegistry); } @@ -2099,8 +2099,8 @@ interface RCTViewManager : public NSObject { } interface RCTViewRegistry : public NSObject { - public virtual UIView* viewForReactTag:(NSNumber* reactTag); - public virtual void addUIBlock:(RCTViewRegistryUIBlock block); + public virtual _Nullable UIView* viewForReactTag:(NSNumber* reactTag); + public virtual void addUIBlock:(_Nullable RCTViewRegistryUIBlock block); public virtual void setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider bridgelessComponentViewProvider); } @@ -2563,8 +2563,8 @@ protocol RCTBridgeModule : public NSObject { public @property (weak) RCTCallableJSModules* callableJSModules; public @property (weak) RCTModuleRegistry* moduleRegistry; public @property (weak, readonly) RCTBridge* bridge; - public virtual NSArray>* methodsToExport(); public virtual NSDictionary* constantsToExport(); + public virtual _Nullable NSArray>* methodsToExport(); public virtual static BOOL requiresMainQueueSetup(); public virtual static NSString* moduleName(); public virtual void batchDidComplete();