diff --git a/Package.resolved b/Package.resolved index 72d6eee..cc7a3e4 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-syntax.git", "state" : { - "revision" : "fa8f95c2d536d6620cc2f504ebe8a6167c9fc2dd", - "version" : "510.0.1" + "revision" : "303e5c5c36d6a558407d364878df131c3546fad8", + "version" : "510.0.2" } } ], diff --git a/Package.swift b/Package.swift index 5d6c7c3..cc3136b 100644 --- a/Package.swift +++ b/Package.swift @@ -40,7 +40,7 @@ let package = Package( .library(name: "ReactBridge", targets: ["ReactBridge"]) ], dependencies: [ - .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.1") + .package(url: "https://github.com/apple/swift-syntax.git", from: "510.0.2") ], targets: [ .macro( @@ -52,9 +52,9 @@ let package = Package( ), .target( name: "ReactBridge", - dependencies: ["ReactBridgeMacros", "RegisterModules"] + dependencies: ["ReactBridgeMacros", "ReactBridgeUtils"] ), - .target(name: "RegisterModules"), + .target(name: "ReactBridgeUtils"), .testTarget( name: "ReactBridgeTests", dependencies: [ diff --git a/Sources/ReactBridge/ReactBridge.swift b/Sources/ReactBridge/ReactBridge.swift index 55c83dc..cf47d77 100644 --- a/Sources/ReactBridge/ReactBridge.swift +++ b/Sources/ReactBridge/ReactBridge.swift @@ -24,6 +24,7 @@ // import Foundation +@_exported import ReactBridgeUtils /// The macro exports and registers a class as a native module for React Native. diff --git a/Sources/ReactBridgeMacros/ReactMethod.swift b/Sources/ReactBridgeMacros/ReactMethod.swift index de6d78c..4b834b3 100644 --- a/Sources/ReactBridgeMacros/ReactMethod.swift +++ b/Sources/ReactBridgeMacros/ReactMethod.swift @@ -27,35 +27,22 @@ import SwiftSyntax import SwiftSyntaxMacros import SwiftDiagnostics + fileprivate extension String { var uppercasedFirst: String { prefix(1).uppercased() + dropFirst() } } - struct ReactMethod { } extension ReactMethod: PeerMacro { - private static var nonisolatedUnsafe: String = { -#if swift(>=5.10) - "nonisolated(unsafe) " -#else - "" -#endif - }() - static func reactExport(funcName: String, jsName: String, objcName: String, isSync: Bool) -> DeclSyntax { """ - @objc static func __rct_export__\(raw: funcName)() -> UnsafePointer? { - struct Static { - static let jsName = strdup(\(raw: jsName)) - static let objcName = strdup("\(raw: objcName)") - \(raw: Self.nonisolatedUnsafe)static var methodInfo = RCTMethodInfo(jsName: jsName, objcName: objcName, isSync: \(raw: isSync)) - } - return withUnsafePointer(to: &Static.methodInfo) { $0 } + @objc static func __rct_export__\(raw: funcName)() -> UnsafeRawPointer { + ReactBridgeUtils.methodInfo(\(raw: jsName), objcName: "\(raw: objcName)", isSync: \(raw: isSync)) } """ } diff --git a/Sources/RegisterModules/RegisterModules.m b/Sources/ReactBridgeUtils/ReactBridgeUtils.m similarity index 74% rename from Sources/RegisterModules/RegisterModules.m rename to Sources/ReactBridgeUtils/ReactBridgeUtils.m index 1f4fc77..7ed90a6 100644 --- a/Sources/RegisterModules/RegisterModules.m +++ b/Sources/ReactBridgeUtils/ReactBridgeUtils.m @@ -1,5 +1,5 @@ // -// RegisterModules.m +// ReactBridgeUtils.m // // Created by Iurii Khvorost on 2023/07/24. // Copyright © 2023 Iurii Khvorost. All rights reserved. @@ -24,9 +24,20 @@ // #import +#import +#import "ReactBridgeUtils.h" -__attribute__((constructor)) -static void registerModules(void) { + +// From RCTBridgeModule.h +typedef struct RCTMethodInfo { + const char * jsName; + const char * objcName; + BOOL isSync; +} RCTMethodInfo; + +@implementation ReactBridgeUtils + ++ (void)load { SEL selector = @selector(_registerModule); int numClasses = objc_getClassList(NULL, 0); @@ -50,3 +61,13 @@ static void registerModules(void) { } free(classes); } + ++ (const void *)methodInfo:(NSString *)jsName objcName:(NSString *)objcName isSync:(BOOL)isSync { + RCTMethodInfo* methodInfo = malloc(sizeof(RCTMethodInfo)); + methodInfo->jsName = strdup([jsName cStringUsingEncoding: NSUTF8StringEncoding]); + methodInfo->objcName = strdup([objcName cStringUsingEncoding: NSUTF8StringEncoding]); + methodInfo->isSync = isSync; + return methodInfo; +} + +@end diff --git a/Sources/ReactBridgeUtils/include/ReactBridgeUtils.h b/Sources/ReactBridgeUtils/include/ReactBridgeUtils.h new file mode 100644 index 0000000..3dff35a --- /dev/null +++ b/Sources/ReactBridgeUtils/include/ReactBridgeUtils.h @@ -0,0 +1,11 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ReactBridgeUtils: NSObject + ++ (const void *)methodInfo:(NSString *)jsName objcName:(NSString *)objcName isSync:(BOOL)isSync; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/ReactBridgeUtils/include/module.modulemap b/Sources/ReactBridgeUtils/include/module.modulemap new file mode 100644 index 0000000..9276cee --- /dev/null +++ b/Sources/ReactBridgeUtils/include/module.modulemap @@ -0,0 +1,3 @@ +module ReactBridgeUtils { + header "ReactBridgeUtils.h" +} diff --git a/Sources/RegisterModules/include/main.h b/Sources/RegisterModules/include/main.h deleted file mode 100644 index e69de29..0000000 diff --git a/Tests/ReactBridgeTests/ReactBridgeTests.swift b/Tests/ReactBridgeTests/ReactBridgeTests.swift index 0d7f47a..6330a1a 100644 --- a/Tests/ReactBridgeTests/ReactBridgeTests.swift +++ b/Tests/ReactBridgeTests/ReactBridgeTests.swift @@ -25,15 +25,8 @@ final class ReactMethodTests: XCTestCase { func rct_export(name: String, selector: String, isSync: Bool = false, jsName: String? = nil) -> String { """ - @objc static func __rct_export__\(name)() -> UnsafePointer? { - struct Static { - static let jsName = strdup("\(jsName ?? name)") - static let objcName = strdup("\(selector)") - \(Self.nonisolatedUnsafe)static var methodInfo = RCTMethodInfo(jsName: jsName, objcName: objcName, isSync: \(isSync)) - } - return withUnsafePointer(to: &Static.methodInfo) { - $0 - } + @objc static func __rct_export__\(name)() -> UnsafeRawPointer { + ReactBridgeUtils.methodInfo("\(jsName ?? name)", objcName: "\(selector)", isSync: \(isSync)) } """ }