From da8b50cd33df692495c06332c995206351d72d57 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005325676 Date: Tue, 29 Sep 2020 04:10:45 -0700 Subject: [PATCH 01/52] Daily `arc lint --take CLANGFORMAT` Reviewed By: zertosh Differential Revision: D23986055 fbshipit-source-id: 7bfe9f06f236f8866e812db060edf3d089fe253c --- React/Views/RCTDatePicker.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/React/Views/RCTDatePicker.m b/React/Views/RCTDatePicker.m index 9fee82b3cfffc2..064191b3e8aa1c 100644 --- a/React/Views/RCTDatePicker.m +++ b/React/Views/RCTDatePicker.m @@ -14,11 +14,11 @@ #import "UIView+React.h" #ifndef __IPHONE_14_0 - #define __IPHONE_14_0 140000 +#define __IPHONE_14_0 140000 #endif // __IPHONE_14_0 #ifndef RCT_IOS_14_0_SDK_OR_LATER - #define RCT_IOS_14_0_SDK_OR_LATER (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0) +#define RCT_IOS_14_0_SDK_OR_LATER (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0) #endif // RCT_IOS_14_0_SDK_OR_LATER @interface RCTDatePicker () From 121141c86b75b46fe9cbd5ec36853d75cd33615b Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Tue, 29 Sep 2020 05:14:48 -0700 Subject: [PATCH 02/52] Convert AndroidDialogPicker to JS view configs Summary: Convert AndroidDialogPicker to JS view configs Changelog: [Internal] Reviewed By: ejanzer Differential Revision: D23911673 fbshipit-source-id: d5fefa997432f0096308ab5593ba74c2c07b71e1 --- .../AndroidDialogPickerNativeComponent.js | 21 ++++++++++--- .../Picker/AndroidDialogPickerViewConfig.js | 30 +++++++++++++++++++ .../views/picker/ReactPickerManager.java | 12 +++----- 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 Libraries/Components/Picker/AndroidDialogPickerViewConfig.js diff --git a/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js b/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js index bac74826a1fb11..d01757865909fc 100644 --- a/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js +++ b/Libraries/Components/Picker/AndroidDialogPickerNativeComponent.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow strict-local + * @flow */ 'use strict'; @@ -14,6 +14,8 @@ import * as React from 'react'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import requireNativeComponent from '../../ReactNative/requireNativeComponent'; +import registerGeneratedViewConfig from '../../Utilities/registerGeneratedViewConfig'; +import AndroidDialogPickerViewConfig from './AndroidDialogPickerViewConfig'; import type { DirectEventHandler, @@ -64,6 +66,17 @@ export const Commands: NativeCommands = codegenNativeCommands({ supportedCommands: ['setNativeSelectedPosition'], }); -export default (requireNativeComponent( - 'AndroidDialogPicker', -): NativeType); +let AndroidDialogPickerNativeComponent; +if (global.RN$Bridgeless) { + registerGeneratedViewConfig( + 'AndroidDialogPicker', + AndroidDialogPickerViewConfig, + ); + AndroidDialogPickerNativeComponent = 'AndroidDialogPicker'; +} else { + AndroidDialogPickerNativeComponent = requireNativeComponent( + 'AndroidDialogPicker', + ); +} + +export default ((AndroidDialogPickerNativeComponent: any): NativeType); diff --git a/Libraries/Components/Picker/AndroidDialogPickerViewConfig.js b/Libraries/Components/Picker/AndroidDialogPickerViewConfig.js new file mode 100644 index 00000000000000..1108b8105e37e1 --- /dev/null +++ b/Libraries/Components/Picker/AndroidDialogPickerViewConfig.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {GeneratedViewConfig} from '../../Utilities/registerGeneratedViewConfig'; + +const AndroidDialogPickerViewConfig = { + uiViewClassName: 'AndroidDialogPicker', + bubblingEventTypes: {}, + directEventTypes: {}, + validAttributes: { + color: {process: require('../../StyleSheet/processColor')}, + backgroundColor: {process: require('../../StyleSheet/processColor')}, + enabled: true, + items: true, + prompt: true, + selected: true, + onSelect: true, + }, +}; + +module.exports = (AndroidDialogPickerViewConfig: GeneratedViewConfig); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java index e5c42e059905e6..ffc46232aa9994 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java @@ -13,7 +13,7 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.events.EventDispatcher; @@ -62,13 +62,9 @@ protected void onAfterUpdateTransaction(ReactPicker view) { @Override protected void addEventEmitters(final ThemedReactContext reactContext, final ReactPicker picker) { - UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); - - if (uiManager == null) { - return; - } - - picker.setOnSelectListener(new PickerEventEmitter(picker, uiManager.getEventDispatcher())); + picker.setOnSelectListener( + new PickerEventEmitter( + picker, UIManagerHelper.getEventDispatcherForReactTag(reactContext, picker.getId()))); } @Override From 5ccb5f5b8002e2301c9ae7292f1f9ab62feab4c0 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Tue, 29 Sep 2020 06:42:20 -0700 Subject: [PATCH 03/52] Fix dismissal animation of Modal Component Summary: Changelog: [Internal] Fabric removes components bottom up (from leafs to the root). This means that by the time Fabric hides Modal, it has no content and therefore it appears as if Modal disappears without Animation. To fix this, we snapshot contents of the Modal before any of its contents are removed. Reviewed By: shergin Differential Revision: D23976244 fbshipit-source-id: 01c13b74e97f82816e8946fd9d1add1db10340b1 --- .../Modal/RCTFabricModalHostViewController.mm | 14 -------------- .../Modal/RCTModalHostViewComponentView.h | 3 ++- .../Modal/RCTModalHostViewComponentView.mm | 13 +++++++++++++ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm b/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm index 54061f535d79ee..dc852ff001da6d 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.mm @@ -56,20 +56,6 @@ - (BOOL)prefersStatusBarHidden return [RCTSharedApplication() isStatusBarHidden]; } -- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)())completion -{ - UIView *snapshot = [self.view snapshotViewAfterScreenUpdates:NO]; - [self.view addSubview:snapshot]; - - [super dismissViewControllerAnimated:flag - completion:^{ - [snapshot removeFromSuperview]; - if (completion) { - completion(); - } - }]; -} - #if RCT_DEV - (UIInterfaceOrientationMask)supportedInterfaceOrientations { diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h index 16fbdfb9624ab7..b61196c4c57b0a 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h @@ -5,12 +5,13 @@ * LICENSE file in the root directory of this source tree. */ +#import #import /** * UIView class for root component. */ -@interface RCTModalHostViewComponentView : RCTViewComponentView +@interface RCTModalHostViewComponentView : RCTViewComponentView /** * Subclasses may override this method and present the modal on different view controller. diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm index 65f2f6ce266300..01648dd2f423d9 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm @@ -101,6 +101,7 @@ @implementation RCTModalHostViewComponentView { ModalHostViewShadowNode::ConcreteStateTeller _stateTeller; BOOL _shouldAnimatePresentation; BOOL _isPresented; + UIView *_modalContentsSnapshot; } - (instancetype)initWithFrame:(CGRect)frame @@ -161,10 +162,22 @@ - (void)ensurePresentedOnlyIfNeeded BOOL shouldBeHidden = _isPresented && !self.superview; if (shouldBeHidden) { _isPresented = NO; + // To animate dismissal of view controller, snapshot of + // view hierarchy needs to be added to the UIViewController. + [self.viewController.view addSubview:_modalContentsSnapshot]; [self dismissViewController:self.viewController animated:_shouldAnimatePresentation]; } } +#pragma mark - RCTMountingTransactionObserving + +- (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata +{ + _modalContentsSnapshot = [self.viewController.view snapshotViewAfterScreenUpdates:NO]; +} + +#pragma mark - UIView methods + - (void)didMoveToWindow { [super didMoveToWindow]; From c06f765f7d73077feee1285dc56f01a32e63fe0c Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Tue, 29 Sep 2020 13:16:57 -0700 Subject: [PATCH 04/52] Allow Java classes to hook into ScrollView scroll and layout events Summary: For advanced interop cases. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D23984345 fbshipit-source-id: f5c2a43a1bf5937f9974bcc5c66c36ec35e679c5 --- .../scroll/ReactHorizontalScrollView.java | 1 + .../react/views/scroll/ReactScrollView.java | 1 + .../views/scroll/ReactScrollViewHelper.java | 31 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 61b1a712332a5d..b632671b712b6c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -266,6 +266,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { int scrollToY = pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY(); reactScrollTo(scrollToX, scrollToY); + ReactScrollViewHelper.emitLayoutEvent(this); } /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 6497c6bce989b2..118579c886f109 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -223,6 +223,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { int scrollToY = pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY(); reactScrollTo(scrollToX, scrollToY); + ReactScrollViewHelper.emitLayoutEvent(this); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java index 5183f24c44bd80..c10a38ebdb02aa 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java @@ -14,6 +14,8 @@ import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReactContext; import com.facebook.react.uimanager.UIManagerHelper; +import java.util.ArrayList; +import java.util.List; /** Helper class that deals with emitting Scroll Events. */ public class ReactScrollViewHelper { @@ -23,6 +25,16 @@ public class ReactScrollViewHelper { public static final String AUTO = "auto"; public static final String OVER_SCROLL_NEVER = "never"; + public interface ScrollListener { + void onScroll( + ViewGroup scrollView, ScrollEventType scrollEventType, float xVelocity, float yVelocity); + + void onLayout(ViewGroup scrollView); + } + + // Support global native listeners for scroll events + private static List sScrollListeners = new ArrayList<>(); + // If all else fails, this is the hardcoded value in OverScroller.java, in AOSP. // The default is defined here (as of this diff): // https://android.googlesource.com/platform/frameworks/base/+/ae5bcf23b5f0875e455790d6af387184dbd009c1/core/java/android/widget/OverScroller.java#44 @@ -64,6 +76,10 @@ private static void emitScrollEvent( return; } + for (ScrollListener scrollListener : sScrollListeners) { + scrollListener.onScroll(scrollView, scrollEventType, xVelocity, yVelocity); + } + ReactContext reactContext = (ReactContext) scrollView.getContext(); UIManagerHelper.getEventDispatcherForReactTag(reactContext, scrollView.getId()) .dispatchEvent( @@ -80,6 +96,13 @@ private static void emitScrollEvent( scrollView.getHeight())); } + /** This is only for Java listeners. onLayout events emitted to JS are handled elsewhere. */ + public static void emitLayoutEvent(ViewGroup scrollView) { + for (ScrollListener scrollListener : sScrollListeners) { + scrollListener.onLayout(scrollView); + } + } + public static int parseOverScrollMode(String jsOverScrollMode) { if (jsOverScrollMode == null || jsOverScrollMode.equals(AUTO)) { return View.OVER_SCROLL_IF_CONTENT_SCROLLS; @@ -130,4 +153,12 @@ public void startScroll(int startX, int startY, int dx, int dy, int duration) { mScrollAnimationDuration = duration; } } + + public static void addScrollListener(ScrollListener listener) { + sScrollListeners.add(listener); + } + + public static void removeScrollListener(ScrollListener listener) { + sScrollListeners.remove(listener); + } } From a7c026e667bb39bef1c8e4b956c6d0c31e43bb31 Mon Sep 17 00:00:00 2001 From: Paige Sun Date: Tue, 29 Sep 2020 14:15:45 -0700 Subject: [PATCH 05/52] Remove unused Fabric image instrumentation Summary: Remove the older implementation of image instrumentation in Fabric by removing, RCTImageInstrumentationProxy, ImageInstrumentation from ImageRequest, and trackURLImageContentDidSetForRequest from RCTImageLoaderWithAttributionProtocol. Changelog: [RN][Fabric][Image] Remove unused Fabric image instrumentation Reviewed By: fkgozali Differential Revision: D23990606 fbshipit-source-id: 004d04025d031af11377a73e5bfb64b1e0449962 --- Libraries/Image/RCTImageLoader.mm | 13 --- .../RCTImageLoaderWithAttributionProtocol.h | 5 -- .../Image/RCTImageURLLoaderWithAttribution.h | 5 -- .../Image/RCTImageComponentView.mm | 7 -- .../components/image/ImageShadowNode.h | 2 +- .../components/slider/SliderShadowNode.h | 8 +- ReactCommon/react/renderer/imagemanager/BUCK | 1 - .../imagemanager/ImageInstrumentation.h | 40 --------- .../renderer/imagemanager/ImageRequest.h | 23 +----- .../renderer/imagemanager/ImageManager.cpp | 2 +- .../renderer/imagemanager/ImageRequest.cpp | 21 +---- .../platform/ios/ImageRequest.cpp | 20 +---- .../ios/RCTImageInstrumentationProxy.h | 40 --------- .../ios/RCTImageInstrumentationProxy.mm | 81 ------------------- .../platform/ios/RCTImageManager.mm | 8 +- .../platform/ios/RCTSyncImageManager.mm | 2 +- 16 files changed, 15 insertions(+), 263 deletions(-) delete mode 100644 ReactCommon/react/renderer/imagemanager/ImageInstrumentation.h delete mode 100644 ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.h delete mode 100644 ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.mm diff --git a/Libraries/Image/RCTImageLoader.mm b/Libraries/Image/RCTImageLoader.mm index 0ea5a4a0c988f9..723b64dbe6184b 100644 --- a/Libraries/Image/RCTImageLoader.mm +++ b/Libraries/Image/RCTImageLoader.mm @@ -831,19 +831,6 @@ - (NSString *)loaderModuleNameForRequestUrl:(NSURL *)url { return nil; } -- (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderRequest -{ - if (!loaderRequest) { - return; - } - - // This delegate method is Fabric-only - id loadHandler = [self imageURLLoaderForURL:loaderRequest.imageURL]; - if ([loadHandler respondsToSelector:@selector(trackURLImageContentDidSetForRequest:)]) { - [(id)loadHandler trackURLImageContentDidSetForRequest:loaderRequest]; - } -} - - (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(UIView *)imageView { if (!loaderRequest || !imageView) { diff --git a/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h b/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h index bd26221531b8a4..44f4ee849a4a75 100644 --- a/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h +++ b/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h @@ -36,11 +36,6 @@ RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled); completionBlock:(RCTImageLoaderCompletionBlockWithMetadata)completionBlock; #endif -/** - * Image instrumentation - notify that the image content (UIImage) has been set on the native view. - */ -- (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderRequest; - /** * Image instrumentation - start tracking the on-screen visibility of the native image view. */ diff --git a/Libraries/Image/RCTImageURLLoaderWithAttribution.h b/Libraries/Image/RCTImageURLLoaderWithAttribution.h index b05ebfba8adfdf..4013367b4d3c63 100644 --- a/Libraries/Image/RCTImageURLLoaderWithAttribution.h +++ b/Libraries/Image/RCTImageURLLoaderWithAttribution.h @@ -59,11 +59,6 @@ struct ImageURLLoaderAttribution { completionHandler:(RCTImageLoaderCompletionBlockWithMetadata)completionHandler; #endif -/** - * Image instrumentation - notify that the image content (UIImage) has been set on the native view. - */ -- (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderRequest; - /** * Image instrumentation - start tracking the on-screen visibility of the native image view. */ diff --git a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index ce8e55c0229fb6..09dd599650f026 100644 --- a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -13,9 +13,7 @@ #import #import #import -#import #import -#import #import using namespace facebook::react; @@ -160,11 +158,6 @@ - (void)didReceiveImage:(UIImage *)image metadata:(id)metadata fromObserver:(voi if (!data.hasValue()) { return; } - auto instrumentation = std::static_pointer_cast( - data.value().getImageRequest().getSharedImageInstrumentation()); - if (instrumentation) { - instrumentation->didSetImage(); - } }; if (imageProps.blurRadius > __FLT_EPSILON__) { diff --git a/ReactCommon/react/renderer/components/image/ImageShadowNode.h b/ReactCommon/react/renderer/components/image/ImageShadowNode.h index 12490840b611bd..0e60f78deef2dd 100644 --- a/ReactCommon/react/renderer/components/image/ImageShadowNode.h +++ b/ReactCommon/react/renderer/components/image/ImageShadowNode.h @@ -46,7 +46,7 @@ class ImageShadowNode final : public ConcreteViewShadowNode< ShadowNodeFamilyFragment const &familyFragment, ComponentDescriptor const &componentDescriptor) { auto imageSource = ImageSource{ImageSource::Type::Invalid}; - return {imageSource, {imageSource, nullptr, nullptr}, 0}; + return {imageSource, {imageSource, nullptr}, 0}; } #pragma mark - LayoutableShadowNode diff --git a/ReactCommon/react/renderer/components/slider/SliderShadowNode.h b/ReactCommon/react/renderer/components/slider/SliderShadowNode.h index c012ff45a517fa..82ab4d0b1dc6c2 100644 --- a/ReactCommon/react/renderer/components/slider/SliderShadowNode.h +++ b/ReactCommon/react/renderer/components/slider/SliderShadowNode.h @@ -44,13 +44,13 @@ class SliderShadowNode final : public ConcreteViewShadowNode< ComponentDescriptor const &componentDescriptor) { auto imageSource = ImageSource{ImageSource::Type::Invalid}; return {imageSource, - {imageSource, nullptr, nullptr}, + {imageSource, nullptr}, imageSource, - {imageSource, nullptr, nullptr}, + {imageSource, nullptr}, imageSource, - {imageSource, nullptr, nullptr}, + {imageSource, nullptr}, imageSource, - {imageSource, nullptr, nullptr}}; + {imageSource, nullptr}}; } #pragma mark - LayoutableShadowNode diff --git a/ReactCommon/react/renderer/imagemanager/BUCK b/ReactCommon/react/renderer/imagemanager/BUCK index a9797d2884b068..52f99b3fec6fc0 100644 --- a/ReactCommon/react/renderer/imagemanager/BUCK +++ b/ReactCommon/react/renderer/imagemanager/BUCK @@ -70,7 +70,6 @@ rn_xplat_cxx_library( ios_exported_headers = subdir_glob( [ ("", "*.h"), - ("platform/ios", "RCTImageInstrumentationProxy.h"), ("platform/ios", "RCTImagePrimitivesConversions.h"), ], prefix = "react/renderer/imagemanager", diff --git a/ReactCommon/react/renderer/imagemanager/ImageInstrumentation.h b/ReactCommon/react/renderer/imagemanager/ImageInstrumentation.h deleted file mode 100644 index c1671cb6790376..00000000000000 --- a/ReactCommon/react/renderer/imagemanager/ImageInstrumentation.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -namespace facebook { -namespace react { - -/* - * A base class for performing image loading instrumentation. - * The actual instrumentation is app, platform, and image loader-specific. - */ -class ImageInstrumentation { - public: - virtual ~ImageInstrumentation() noexcept = default; - - /** - * Mark that the image content is set on the native image component on screen. - */ - virtual void didSetImage() const = 0; - - /** - * Mark that the image view starts to be visible on screen. - */ - virtual void didEnterVisibilityRange() const = 0; - - /** - * Mark that the image view is no longer visible on screen. - */ - virtual void didExitVisibilityRange() const = 0; -}; - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/react/renderer/imagemanager/ImageRequest.h b/ReactCommon/react/renderer/imagemanager/ImageRequest.h index a77c1f76c794dd..e3f3047566429a 100644 --- a/ReactCommon/react/renderer/imagemanager/ImageRequest.h +++ b/ReactCommon/react/renderer/imagemanager/ImageRequest.h @@ -7,7 +7,6 @@ #pragma once -#include #include #include #include @@ -31,8 +30,7 @@ class ImageRequest final { */ ImageRequest( const ImageSource &imageSource, - std::shared_ptr telemetry, - std::shared_ptr instrumentation); + std::shared_ptr telemetry); /* * The move constructor. @@ -78,20 +76,6 @@ class ImageRequest final { */ const std::shared_ptr &getSharedTelemetry() const; - /* - * Returns stored image instrumentation object as a shared pointer. - * Retain this *or* `ImageRequest` to ensure a correct lifetime of the object. - */ - const std::shared_ptr - &getSharedImageInstrumentation() const; - - /* - * Returns the image instrumentation object specific to this request. - * Use this if a correct lifetime of the object is ensured in some other way - * (e.g. by retaining an `ImageRequest`). - */ - const ImageInstrumentation &getImageInstrumentation() const; - private: /* * Image source associated with the request. @@ -108,11 +92,6 @@ class ImageRequest final { */ std::shared_ptr coordinator_{}; - /* - * Image instrumentation specific to the request. - */ - std::shared_ptr instrumentation_; - /* * Function we can call to cancel image request (see destructor). */ diff --git a/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageManager.cpp b/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageManager.cpp index c1d4d1ac63e7b4..245c3b5e7a783b 100644 --- a/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageManager.cpp +++ b/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageManager.cpp @@ -24,7 +24,7 @@ ImageRequest ImageManager::requestImage( const ImageSource &imageSource, SurfaceId surfaceId) const { // Not implemented. - return ImageRequest(imageSource, nullptr, nullptr); + return ImageRequest(imageSource, nullptr); } } // namespace react diff --git a/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequest.cpp b/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequest.cpp index 9cdbc7fdd0dda0..9f811bc4d4a3d2 100644 --- a/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequest.cpp +++ b/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequest.cpp @@ -12,19 +12,15 @@ namespace react { ImageRequest::ImageRequest( const ImageSource &imageSource, - std::shared_ptr telemetry, - std::shared_ptr instrumentation) - : imageSource_(imageSource), - telemetry_(telemetry), - instrumentation_(instrumentation) { + std::shared_ptr telemetry) + : imageSource_(imageSource), telemetry_(telemetry) { // Not implemented. } ImageRequest::ImageRequest(ImageRequest &&other) noexcept : imageSource_(std::move(other.imageSource_)), telemetry_(std::move(other.telemetry_)), - coordinator_(std::move(other.coordinator_)), - instrumentation_(std::move(other.instrumentation_)) { + coordinator_(std::move(other.coordinator_)) { // Not implemented. } @@ -44,16 +40,5 @@ const std::shared_ptr abort(); } -const std::shared_ptr - &ImageRequest::getSharedImageInstrumentation() const { - // Not implemented - abort(); -} - -const ImageInstrumentation &ImageRequest::getImageInstrumentation() const { - // Not implemented - abort(); -} - } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/imagemanager/platform/ios/ImageRequest.cpp b/ReactCommon/react/renderer/imagemanager/platform/ios/ImageRequest.cpp index 216e1ffdfd986d..ce7f9b2d04549f 100644 --- a/ReactCommon/react/renderer/imagemanager/platform/ios/ImageRequest.cpp +++ b/ReactCommon/react/renderer/imagemanager/platform/ios/ImageRequest.cpp @@ -12,24 +12,19 @@ namespace react { ImageRequest::ImageRequest( const ImageSource &imageSource, - std::shared_ptr telemetry, - std::shared_ptr instrumentation) - : imageSource_(imageSource), - telemetry_(telemetry), - instrumentation_(instrumentation) { + std::shared_ptr telemetry) + : imageSource_(imageSource), telemetry_(telemetry) { coordinator_ = std::make_shared(); } ImageRequest::ImageRequest(ImageRequest &&other) noexcept : imageSource_(std::move(other.imageSource_)), telemetry_(std::move(other.telemetry_)), - coordinator_(std::move(other.coordinator_)), - instrumentation_(std::move(other.instrumentation_)) { + coordinator_(std::move(other.coordinator_)) { other.moved_ = true; other.coordinator_ = nullptr; other.cancelRequest_ = nullptr; other.telemetry_ = nullptr; - other.instrumentation_ = nullptr; } ImageRequest::~ImageRequest() { @@ -58,14 +53,5 @@ const std::shared_ptr return coordinator_; } -const std::shared_ptr - &ImageRequest::getSharedImageInstrumentation() const { - return instrumentation_; -} - -const ImageInstrumentation &ImageRequest::getImageInstrumentation() const { - return *instrumentation_; -} - } // namespace react } // namespace facebook diff --git a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.h b/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.h deleted file mode 100644 index 95726a5ff0cccf..00000000000000 --- a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include -#include - -NS_ASSUME_NONNULL_BEGIN - -namespace facebook { -namespace react { - -class RCTImageInstrumentationProxy final : public ImageInstrumentation { - public: - RCTImageInstrumentationProxy(id imageLoader); - ~RCTImageInstrumentationProxy(); - - void didSetImage() const override; - void didEnterVisibilityRange() const override; - void didExitVisibilityRange() const override; - - void trackNativeImageView(UIView *imageView) const; - void setImageURLLoaderRequest(RCTImageURLLoaderRequest *request); - - private: - __weak id imageLoader_; - RCTImageURLLoaderRequest *imageURLLoaderRequest_; -}; - -} // namespace react -} // namespace facebook - -NS_ASSUME_NONNULL_END diff --git a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.mm b/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.mm deleted file mode 100644 index 1ed24f9faacda3..00000000000000 --- a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageInstrumentationProxy.mm +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import "RCTImageInstrumentationProxy.h" - -namespace facebook { -namespace react { - -RCTImageInstrumentationProxy::RCTImageInstrumentationProxy(id imageLoader) - : imageLoader_(imageLoader) -{ -} - -RCTImageInstrumentationProxy::~RCTImageInstrumentationProxy() -{ - if (!imageURLLoaderRequest_) { - return; - } - [imageLoader_ trackURLImageDidDestroy:imageURLLoaderRequest_]; -} - -void RCTImageInstrumentationProxy::didSetImage() const -{ - if (!RCTImageLoadingPerfInstrumentationEnabled()) { - return; - } - - if (!imageURLLoaderRequest_) { - return; - } - - [imageLoader_ trackURLImageContentDidSetForRequest:imageURLLoaderRequest_]; -} - -void RCTImageInstrumentationProxy::didEnterVisibilityRange() const -{ - if (!RCTImageLoadingPerfInstrumentationEnabled()) { - return; - } - - // TODO (T58941612): Not yet supported. - if (!imageURLLoaderRequest_) { - return; - } -} - -void RCTImageInstrumentationProxy::didExitVisibilityRange() const -{ - if (!RCTImageLoadingPerfInstrumentationEnabled()) { - return; - } - - // TODO (T58941612): Not yet supported. - if (!imageURLLoaderRequest_) { - return; - } -} - -void RCTImageInstrumentationProxy::trackNativeImageView(UIView *imageView) const -{ - if (!RCTImageLoadingPerfInstrumentationEnabled()) { - return; - } - - if (!imageURLLoaderRequest_) { - return; - } - [imageLoader_ trackURLImageVisibilityForRequest:imageURLLoaderRequest_ imageView:imageView]; -} - -void RCTImageInstrumentationProxy::setImageURLLoaderRequest(RCTImageURLLoaderRequest *request) -{ - imageURLLoaderRequest_ = request; -} - -} // namespace react -} // namespace facebook diff --git a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageManager.mm b/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageManager.mm index b719be1158fbb8..08e0c255885d3f 100644 --- a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageManager.mm +++ b/ReactCommon/react/renderer/imagemanager/platform/ios/RCTImageManager.mm @@ -16,7 +16,6 @@ #import #import -#import "RCTImageInstrumentationProxy.h" #import "RCTImagePrimitivesConversions.h" using namespace facebook::react; @@ -41,10 +40,9 @@ - (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfa { SystraceSection s("RCTImageManager::requestImage"); - auto imageInstrumentation = std::make_shared(_imageLoader); auto telemetry = std::make_shared(surfaceId); telemetry->willRequestUrl(); - auto imageRequest = ImageRequest(imageSource, telemetry, imageInstrumentation); + auto imageRequest = ImageRequest(imageSource, telemetry); auto weakObserverCoordinator = (std::weak_ptr)imageRequest.getSharedObserverCoordinator(); @@ -108,10 +106,6 @@ - (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfa completionBlock:completionBlock]; RCTImageLoaderCancellationBlock cancelationBlock = loaderRequest.cancellationBlock; sharedCancelationFunction.assign([cancelationBlock]() { cancelationBlock(); }); - - if (imageInstrumentation) { - imageInstrumentation->setImageURLLoaderRequest(loaderRequest); - } }); return imageRequest; diff --git a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTSyncImageManager.mm b/ReactCommon/react/renderer/imagemanager/platform/ios/RCTSyncImageManager.mm index df89da51cecf31..7a36d42ea4a283 100644 --- a/ReactCommon/react/renderer/imagemanager/platform/ios/RCTSyncImageManager.mm +++ b/ReactCommon/react/renderer/imagemanager/platform/ios/RCTSyncImageManager.mm @@ -37,7 +37,7 @@ - (instancetype)initWithImageLoader:(id)i - (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfaceId { auto telemetry = std::make_shared(surfaceId); - auto imageRequest = ImageRequest(imageSource, telemetry, nullptr); + auto imageRequest = ImageRequest(imageSource, telemetry); auto weakObserverCoordinator = (std::weak_ptr)imageRequest.getSharedObserverCoordinator(); From ef145adb9db646b4133eff7da03691a958854bd0 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 06/52] Split NativeImageStore into iOS and Android counterparts Summary: Split the two specs, so that that we don't have to use Flow unions in the merged spec. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D23800841 fbshipit-source-id: 28b67578832ebd733bd080877e4ab763c013fded --- .../FBReactNativeSpec-generated.mm | 50 ++++++++++++---- .../FBReactNativeSpec/FBReactNativeSpec.h | 57 ++++++++++++++++--- Libraries/Image/NativeImageStoreAndroid.js | 27 +++++++++ ...veImageStore.js => NativeImageStoreIOS.js} | 12 +--- Libraries/Image/RCTImageStoreManager.mm | 4 +- .../specs/NativeImageStoreAndroidSpec.java | 30 ++++++++++ .../specs/NativeImageStoreIOSSpec.java | 40 +++++++++++++ .../specs/jni/FBReactNativeSpec-generated.cpp | 38 ++++++++++--- .../fbreact/specs/jni/FBReactNativeSpec.h | 20 ++++++- .../modules/camera/ImageStoreManager.java | 20 +------ 10 files changed, 235 insertions(+), 63 deletions(-) create mode 100644 Libraries/Image/NativeImageStoreAndroid.js rename Libraries/Image/{NativeImageStore.js => NativeImageStoreIOS.js} (75%) create mode 100644 ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreAndroidSpec.java create mode 100644 ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreIOSSpec.java diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm index 1f7227f478f872..5ca05feb84cd38 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm @@ -1610,46 +1610,72 @@ + (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenSelectDialogConfig:(id)js } // namespace react } // namespace facebook -@implementation RCTCxxConvert (NativeImageStore_SpecAddImageFromBase64ErrorCallbackError) -+ (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackError:(id)json +namespace facebook { + namespace react { + + + static facebook::jsi::Value __hostFunction_NativeImageStoreAndroidSpecJSI_getBase64ForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "getBase64ForTag", @selector(getBase64ForTag:successCallback:errorCallback:), args, count); + } + + + NativeImageStoreAndroidSpecJSI::NativeImageStoreAndroidSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreAndroidSpecJSI_getBase64ForTag}; + + + + } + + } // namespace react +} // namespace facebook +@implementation RCTCxxConvert (NativeImageStoreIOS_SpecGetBase64ForTagErrorCallbackError) ++ (RCTManagedPointer *)JS_NativeImageStoreIOS_SpecGetBase64ForTagErrorCallbackError:(id)json +{ + return facebook::react::managedPointer(json); +} +@end +@implementation RCTCxxConvert (NativeImageStoreIOS_SpecAddImageFromBase64ErrorCallbackError) ++ (RCTManagedPointer *)JS_NativeImageStoreIOS_SpecAddImageFromBase64ErrorCallbackError:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_getBase64ForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_getBase64ForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "getBase64ForTag", @selector(getBase64ForTag:successCallback:errorCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_hasImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_hasImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "hasImageForTag", @selector(hasImageForTag:callback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_removeImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_removeImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "removeImageForTag", @selector(removeImageForTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_addImageFromBase64(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_addImageFromBase64(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "addImageFromBase64", @selector(addImageFromBase64:successCallback:errorCallback:), args, count); } - NativeImageStoreSpecJSI::NativeImageStoreSpecJSI(const ObjCTurboModule::InitParams ¶ms) + NativeImageStoreIOSSpecJSI::NativeImageStoreIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreSpecJSI_getBase64ForTag}; + methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreIOSSpecJSI_getBase64ForTag}; - methodMap_["hasImageForTag"] = MethodMetadata {2, __hostFunction_NativeImageStoreSpecJSI_hasImageForTag}; + methodMap_["hasImageForTag"] = MethodMetadata {2, __hostFunction_NativeImageStoreIOSSpecJSI_hasImageForTag}; - methodMap_["removeImageForTag"] = MethodMetadata {1, __hostFunction_NativeImageStoreSpecJSI_removeImageForTag}; + methodMap_["removeImageForTag"] = MethodMetadata {1, __hostFunction_NativeImageStoreIOSSpecJSI_removeImageForTag}; - methodMap_["addImageFromBase64"] = MethodMetadata {3, __hostFunction_NativeImageStoreSpecJSI_addImageFromBase64}; + methodMap_["addImageFromBase64"] = MethodMetadata {3, __hostFunction_NativeImageStoreIOSSpecJSI_addImageFromBase64}; diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index 93f4a41177323f..78011e9ea4d305 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -1524,9 +1524,45 @@ namespace facebook { }; } // namespace react } // namespace facebook +@protocol NativeImageStoreAndroidSpec + +- (void)getBase64ForTag:(NSString *)uri + successCallback:(RCTResponseSenderBlock)successCallback + errorCallback:(RCTResponseSenderBlock)errorCallback; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ImageStoreAndroid' + */ + + class JSI_EXPORT NativeImageStoreAndroidSpecJSI : public ObjCTurboModule { + public: + NativeImageStoreAndroidSpecJSI(const ObjCTurboModule::InitParams ¶ms); + + }; + } // namespace react +} // namespace facebook namespace JS { - namespace NativeImageStore { + namespace NativeImageStoreIOS { + struct SpecGetBase64ForTagErrorCallbackError { + NSString *message() const; + + SpecGetBase64ForTagErrorCallbackError(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeImageStoreIOS_SpecGetBase64ForTagErrorCallbackError) ++ (RCTManagedPointer *)JS_NativeImageStoreIOS_SpecGetBase64ForTagErrorCallbackError:(id)json; +@end + +namespace JS { + namespace NativeImageStoreIOS { struct SpecAddImageFromBase64ErrorCallbackError { NSString *message() const; @@ -1537,10 +1573,10 @@ namespace JS { } } -@interface RCTCxxConvert (NativeImageStore_SpecAddImageFromBase64ErrorCallbackError) -+ (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackError:(id)json; +@interface RCTCxxConvert (NativeImageStoreIOS_SpecAddImageFromBase64ErrorCallbackError) ++ (RCTManagedPointer *)JS_NativeImageStoreIOS_SpecAddImageFromBase64ErrorCallbackError:(id)json; @end -@protocol NativeImageStoreSpec +@protocol NativeImageStoreIOSSpec - (void)getBase64ForTag:(NSString *)uri successCallback:(RCTResponseSenderBlock)successCallback @@ -1556,12 +1592,12 @@ namespace JS { namespace facebook { namespace react { /** - * ObjC++ class for module 'ImageStore' + * ObjC++ class for module 'ImageStoreIOS' */ - class JSI_EXPORT NativeImageStoreSpecJSI : public ObjCTurboModule { + class JSI_EXPORT NativeImageStoreIOSSpecJSI : public ObjCTurboModule { public: - NativeImageStoreSpecJSI(const ObjCTurboModule::InitParams ¶ms); + NativeImageStoreIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react @@ -3292,7 +3328,12 @@ inline bool JS::NativeImagePickerIOS::SpecOpenSelectDialogConfig::showVideos() c id const p = _v[@"showVideos"]; return RCTBridgingToBool(p); } -inline NSString *JS::NativeImageStore::SpecAddImageFromBase64ErrorCallbackError::message() const +inline NSString *JS::NativeImageStoreIOS::SpecGetBase64ForTagErrorCallbackError::message() const +{ + id const p = _v[@"message"]; + return RCTBridgingToString(p); +} +inline NSString *JS::NativeImageStoreIOS::SpecAddImageFromBase64ErrorCallbackError::message() const { id const p = _v[@"message"]; return RCTBridgingToString(p); diff --git a/Libraries/Image/NativeImageStoreAndroid.js b/Libraries/Image/NativeImageStoreAndroid.js new file mode 100644 index 00000000000000..8ab6dc7c1a2315 --- /dev/null +++ b/Libraries/Image/NativeImageStoreAndroid.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type {TurboModule} from '../TurboModule/RCTExport'; +import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; + +export interface Spec extends TurboModule { + +getConstants: () => {||}; + +getBase64ForTag: ( + uri: string, + successCallback: (base64ImageData: string) => void, + errorCallback: (error: string) => void, + ) => void; +} + +export default (TurboModuleRegistry.getEnforcing( + 'ImageStoreManager', +): Spec); diff --git a/Libraries/Image/NativeImageStore.js b/Libraries/Image/NativeImageStoreIOS.js similarity index 75% rename from Libraries/Image/NativeImageStore.js rename to Libraries/Image/NativeImageStoreIOS.js index 38603b6aaab2cf..d94f1ef4f35095 100644 --- a/Libraries/Image/NativeImageStore.js +++ b/Libraries/Image/NativeImageStoreIOS.js @@ -15,21 +15,11 @@ import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { +getConstants: () => {||}; - // Common +getBase64ForTag: ( uri: string, successCallback: (base64ImageData: string) => void, - - /** - * On Android, the failure callback is called with a string. - * On iOS, the failure callback is called with an error object. - * - * TODO(T47527939) Unify this inconsistency - */ - errorCallback: (error: {|message: string|} | string) => void, + errorCallback: (error: {|message: string|}) => void, ) => void; - - // iOS-only +hasImageForTag: (uri: string, callback: (hasImage: boolean) => void) => void; +removeImageForTag: (uri: string) => void; +addImageFromBase64: ( diff --git a/Libraries/Image/RCTImageStoreManager.mm b/Libraries/Image/RCTImageStoreManager.mm index 907ecbbb6b0871..7eb3b1e91cc3d5 100644 --- a/Libraries/Image/RCTImageStoreManager.mm +++ b/Libraries/Image/RCTImageStoreManager.mm @@ -22,7 +22,7 @@ static NSString *const RCTImageStoreURLScheme = @"rct-image-store"; -@interface RCTImageStoreManager() +@interface RCTImageStoreManager() @end @implementation RCTImageStoreManager @@ -236,7 +236,7 @@ - (void)getImageForTag:(NSString *)imageTag withBlock:(void (^)(UIImage *image)) - (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { - return std::make_shared(params); + return std::make_shared(params); } @end diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreAndroidSpec.java b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreAndroidSpec.java new file mode 100644 index 00000000000000..f3c53ac8544ac5 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreAndroidSpec.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + * + *

Generated by an internal genrule from Flow types. + * + * @generated + * @nolint + */ + +package com.facebook.fbreact.specs; + +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactModuleWithSpec; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; + +public abstract class NativeImageStoreAndroidSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule { + public NativeImageStoreAndroidSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @ReactMethod + public abstract void getBase64ForTag(String uri, Callback successCallback, + Callback errorCallback); +} diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreIOSSpec.java b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreIOSSpec.java new file mode 100644 index 00000000000000..10455469ccec72 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeImageStoreIOSSpec.java @@ -0,0 +1,40 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + * + *

Generated by an internal genrule from Flow types. + * + * @generated + * @nolint + */ + +package com.facebook.fbreact.specs; + +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactModuleWithSpec; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; + +public abstract class NativeImageStoreIOSSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule { + public NativeImageStoreIOSSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @ReactMethod + public abstract void addImageFromBase64(String base64ImageData, Callback successCallback, + Callback errorCallback); + + @ReactMethod + public abstract void getBase64ForTag(String uri, Callback successCallback, + Callback errorCallback); + + @ReactMethod + public abstract void hasImageForTag(String uri, Callback callback); + + @ReactMethod + public abstract void removeImageForTag(String uri); +} diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec-generated.cpp b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec-generated.cpp index 85c52d7e79592a..e8fdde414ba7d9 100644 --- a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec-generated.cpp +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec-generated.cpp @@ -1416,36 +1416,56 @@ namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_getBase64ForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreAndroidSpecJSI_getBase64ForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "getBase64ForTag", "(Ljava/lang/String;Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V", args, count); } - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_hasImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + + NativeImageStoreAndroidSpecJSI::NativeImageStoreAndroidSpecJSI(const JavaTurboModule::InitParams ¶ms) + : JavaTurboModule(params) { + + methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreAndroidSpecJSI_getBase64ForTag}; + + + + } + + } // namespace react +} // namespace facebook +namespace facebook { + namespace react { + + + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_getBase64ForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "getBase64ForTag", "(Ljava/lang/String;Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V", args, count); + } + + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_hasImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "hasImageForTag", "(Ljava/lang/String;Lcom/facebook/react/bridge/Callback;)V", args, count); } - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_removeImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_removeImageForTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "removeImageForTag", "(Ljava/lang/String;)V", args, count); } - static facebook::jsi::Value __hostFunction_NativeImageStoreSpecJSI_addImageFromBase64(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImageStoreIOSSpecJSI_addImageFromBase64(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, "addImageFromBase64", "(Ljava/lang/String;Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V", args, count); } - NativeImageStoreSpecJSI::NativeImageStoreSpecJSI(const JavaTurboModule::InitParams ¶ms) + NativeImageStoreIOSSpecJSI::NativeImageStoreIOSSpecJSI(const JavaTurboModule::InitParams ¶ms) : JavaTurboModule(params) { - methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreSpecJSI_getBase64ForTag}; + methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreIOSSpecJSI_getBase64ForTag}; - methodMap_["hasImageForTag"] = MethodMetadata {2, __hostFunction_NativeImageStoreSpecJSI_hasImageForTag}; + methodMap_["hasImageForTag"] = MethodMetadata {2, __hostFunction_NativeImageStoreIOSSpecJSI_hasImageForTag}; - methodMap_["removeImageForTag"] = MethodMetadata {1, __hostFunction_NativeImageStoreSpecJSI_removeImageForTag}; + methodMap_["removeImageForTag"] = MethodMetadata {1, __hostFunction_NativeImageStoreIOSSpecJSI_removeImageForTag}; - methodMap_["addImageFromBase64"] = MethodMetadata {3, __hostFunction_NativeImageStoreSpecJSI_addImageFromBase64}; + methodMap_["addImageFromBase64"] = MethodMetadata {3, __hostFunction_NativeImageStoreIOSSpecJSI_addImageFromBase64}; diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec.h b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec.h index 940c22e2f62c94..49f97cc402c4d2 100644 --- a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec.h +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec.h @@ -440,12 +440,26 @@ namespace facebook { namespace facebook { namespace react { /** - * C++ class for module 'ImageStore' + * C++ class for module 'ImageStoreAndroid' */ - class JSI_EXPORT NativeImageStoreSpecJSI : public JavaTurboModule { + class JSI_EXPORT NativeImageStoreAndroidSpecJSI : public JavaTurboModule { public: - NativeImageStoreSpecJSI(const JavaTurboModule::InitParams ¶ms); + NativeImageStoreAndroidSpecJSI(const JavaTurboModule::InitParams ¶ms); + + }; + } // namespace react +} // namespace facebook + +namespace facebook { + namespace react { + /** + * C++ class for module 'ImageStoreIOS' + */ + + class JSI_EXPORT NativeImageStoreIOSSpecJSI : public JavaTurboModule { + public: + NativeImageStoreIOSSpecJSI(const JavaTurboModule::InitParams ¶ms); }; } // namespace react diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.java b/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.java index 8bf377cfb4cc13..0752be6e554cae 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/camera/ImageStoreManager.java @@ -12,7 +12,7 @@ import android.os.AsyncTask; import android.util.Base64; import android.util.Base64OutputStream; -import com.facebook.fbreact.specs.NativeImageStoreSpec; +import com.facebook.fbreact.specs.NativeImageStoreAndroidSpec; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.GuardedAsyncTask; import com.facebook.react.bridge.ReactApplicationContext; @@ -25,7 +25,7 @@ import java.io.InputStream; @ReactModule(name = ImageStoreManager.NAME) -public class ImageStoreManager extends NativeImageStoreSpec { +public class ImageStoreManager extends NativeImageStoreAndroidSpec { public static final String NAME = "ImageStoreManager"; private static final int BUFFER_SIZE = 8192; @@ -105,20 +105,4 @@ private static void closeQuietly(Closeable closeable) { // shhh } } - - @Override - public void hasImageForTag(String uri, Callback callback) { - // iOS only - } - - @Override - public void removeImageForTag(String uri) { - // iOS only - } - - @Override - public void addImageFromBase64( - String base64ImageData, Callback successCallback, Callback errorCallback) { - // iOS only - } } From 341e05ff62e1c6e799f5c825fa44308cf1a48485 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 07/52] Allow NativeModule method return types to use type aliases Summary: We already support type-aliases in our NativeModule method params. This diff extends the support to NativeModule method returns. **Note:** I need to see if I need to update the generators to handle this case. Will do that in this diff, after working through other higher priority stuff. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D22828839 fbshipit-source-id: cf5c756d3cacf067df217cdb6212946320a2d4be --- packages/react-native-codegen/src/CodegenSchema.js | 5 +++++ .../parsers/flow/modules/__test_fixtures__/fixtures.js | 2 +- .../__tests__/__snapshots__/module-parser-test.js.snap | 3 ++- .../src/parsers/flow/modules/methods.js | 9 ++++++++- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index ffd3a1a4666173..f827018f020103 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -304,6 +304,11 @@ export type FunctionTypeAnnotationReturn = nullable: boolean, type: 'ObjectTypeAnnotation', properties: ?$ReadOnlyArray, + |}> + | $ReadOnly<{| + nullable: boolean, + type: 'TypeAliasTypeAnnotation', + name: string, |}>; export type FunctionTypeAnnotationReturnArrayElementType = diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index a326be96accd23..c362d7f2ec0f8d 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -200,7 +200,7 @@ type Foo = {| export interface Spec extends TurboModule { // Exported methods. - foo1: (x: Foo) => void; + foo1: (x: Foo) => Foo; foo2: (x: Foo) => void; } diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap index 0aeb307d1b2201..08193385e0a985 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap @@ -940,8 +940,9 @@ Object { }, ], "returnTypeAnnotation": Object { + "name": "Foo", "nullable": false, - "type": "VoidTypeAnnotation", + "type": "TypeAliasTypeAnnotation", }, "type": "FunctionTypeAnnotation", }, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/methods.js b/packages/react-native-codegen/src/parsers/flow/modules/methods.js index c63fc903692d56..2445b5d38e551d 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/methods.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/methods.js @@ -244,6 +244,13 @@ function getReturnTypeAnnotation( ); } case 'ObjectTypeAnnotation': + if (returnType.type === 'GenericTypeAnnotation') { + return { + nullable, + type: 'TypeAliasTypeAnnotation', + name: returnType.id.name, + }; + } return { nullable, type: 'ObjectTypeAnnotation', @@ -323,7 +330,7 @@ function buildMethodSchema( const returnTypeAnnotation = getReturnTypeAnnotation( name, - getValueFromTypes(value.returnType, types), + value.returnType, types, ); return { From 5142e994374eac3e9bbc346796efdc73c61e3171 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 08/52] Delete NativeModuleSchemaBuilderConfig type Summary: Unecessary, since `NativeModuleShape` is the exact same thing. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D23119784 fbshipit-source-id: 8c4aded88a97a80aa977c13cc27e32fbe68150aa --- .../src/parsers/flow/modules/index.js | 5 ++--- .../src/parsers/flow/modules/schema.js | 13 ++----------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index c09c66acf47c51..d8f5e7d4cda476 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -10,7 +10,7 @@ 'use strict'; -import type {NativeModuleSchemaBuilderConfig} from './schema.js'; +import type {NativeModuleShape} from '../../../CodegenSchema'; const {getAliases} = require('./aliases'); const {getMethods} = require('./methods'); @@ -58,8 +58,7 @@ function getModuleAliases(types, aliasNames) { }); } -// $FlowFixMe there's no flowtype for AST -function processModule(types): NativeModuleSchemaBuilderConfig { +function processModule(types: $FlowFixMe): NativeModuleShape { const interfaceName = findInterfaceName(types); const moduleProperties = getModuleProperties(types, interfaceName); const properties = getMethods(moduleProperties, types); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/schema.js b/packages/react-native-codegen/src/parsers/flow/modules/schema.js index c1e4c80cfd5fed..34e6b1531050b3 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/schema.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/schema.js @@ -10,19 +10,10 @@ 'use strict'; -import type { - SchemaType, - ObjectTypeAliasTypeShape, - NativeModuleMethodTypeShape, -} from '../../../CodegenSchema.js'; - -export type NativeModuleSchemaBuilderConfig = $ReadOnly<{| - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, - properties: $ReadOnlyArray, -|}>; +import type {SchemaType, NativeModuleShape} from '../../../CodegenSchema.js'; function buildModuleSchema( - {aliases, properties}: NativeModuleSchemaBuilderConfig, + {aliases, properties}: NativeModuleShape, moduleName: string, ): SchemaType { return { From 1435d654d787ef312f24abcd24f1cf6b2dbf03d7 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 09/52] Restructure getTypes function Summary: There are two types of types we care about: - Type aliases - Interface Declarations These types can be exported. I think we should build the types dictionary from only those types. Everything else should be ignored. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D23120241 fbshipit-source-id: 9f023081d0f9c85b45407b180ae7c3e7391eb725 --- .../src/parsers/flow/index.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index 4de02b0094393d..47342b8d87f9c1 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -20,10 +20,19 @@ const {buildComponentSchema} = require('./components/schema'); const {processComponent} = require('./components'); const {processModule} = require('./modules'); -function getTypes(ast) { +/** + * This FlowFixMe is supposed to refer to an InterfaceDeclaration or TypeAlias + * declaration type. Unfortunately, we don't have those types, because flow-parser + * generates them, and flow-parser is not type-safe. In the future, we should find + * a way to get these types from our flow parser library. + */ +function getTypes(ast): {[declarationName: string]: $FlowFixMe} { return ast.body.reduce((types, node) => { - if (node.type === 'ExportNamedDeclaration') { - if (node.declaration && node.declaration.type !== 'VariableDeclaration') { + if (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type') { + if ( + node.declaration.type === 'TypeAlias' || + node.declaration.type === 'InterfaceDeclaration' + ) { types[node.declaration.id.name] = node.declaration; } } else if ( From 22d6e04da12d7650a9bf0bcf00c2a5f86aaec62a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 10/52] Clean up Module/Component detection logic in Flow parser Summary: Just broke down getConfigType into two separate functions: `isModule` and `isComponent`. - Cleaned up `isComponent`, to check for the the AST node types. - Re-implemented `isModule` - Improved error messages. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D23121896 fbshipit-source-id: 3df2b2e334c4cea8eabe2e73ecb9f1f1217e7be4 --- .../src/parsers/flow/index.js | 83 ++++++++++++------- .../__snapshots__/module-parser-test.js.snap | 7 +- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index 47342b8d87f9c1..aeca0a0a1adeb0 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -26,7 +26,9 @@ const {processModule} = require('./modules'); * generates them, and flow-parser is not type-safe. In the future, we should find * a way to get these types from our flow parser library. */ -function getTypes(ast): {[declarationName: string]: $FlowFixMe} { +type TypeDeclarations = {|[declarationName: string]: $FlowFixMe|}; + +function getTypes(ast): TypeDeclarations { return ast.body.reduce((types, node) => { if (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type') { if ( @@ -45,58 +47,79 @@ function getTypes(ast): {[declarationName: string]: $FlowFixMe} { }, {}); } -function getConfigType(ast, types): 'module' | 'component' { +function isComponent(ast) { const defaultExports = ast.body.filter( node => node.type === 'ExportDefaultDeclaration', ); - let isComponent = false; + if (defaultExports.length === 0) { + return false; + } - if (defaultExports.length > 0) { - let declaration = defaultExports[0].declaration; - // codegenNativeComponent can be nested inside a cast - // expression so we need to go one level deeper - if (declaration.type === 'TypeCastExpression') { - declaration = declaration.expression; - } + let declaration = defaultExports[0].declaration; + // codegenNativeComponent can be nested inside a cast + // expression so we need to go one level deeper + if (declaration.type === 'TypeCastExpression') { + declaration = declaration.expression; + } - isComponent = - declaration && - declaration.callee && - declaration.callee.name === 'codegenNativeComponent'; + if (declaration.type !== 'CallExpression') { + return false; } - const typesExtendingTurboModule = Object.keys(types) - .map(typeName => types[typeName]) - .filter( - type => - type.extends && - type.extends[0] && - type.extends[0].id.name === 'TurboModule', - ); + return ( + declaration.callee.type === 'Identifier' && + declaration.callee.name === 'codegenNativeComponent' + ); +} - if (typesExtendingTurboModule.length > 1) { +function isModule(types: TypeDeclarations) { + const declaredModuleNames: Array = Object.keys(types).filter( + (typeName: string) => { + const declaration = types[typeName]; + return ( + declaration.type === 'InterfaceDeclaration' && + declaration.extends.length === 1 && + declaration.extends[0].type === 'InterfaceExtends' && + declaration.extends[0].id.name === 'TurboModule' + ); + }, + ); + + if (declaredModuleNames.length === 0) { + return false; + } + + if (declaredModuleNames.length > 1) { throw new Error( - 'Found two types extending "TurboModule" is one file. Split them into separated files.', + 'File contains declarations of more than one module: ' + + declaredModuleNames.join(', ') + + '. Please declare exactly one module in this file.', ); } - const isModule = typesExtendingTurboModule.length === 1; + return true; +} + +function getConfigType(ast, types: TypeDeclarations): 'module' | 'component' { + const isConfigAComponent = isComponent(ast); + const isConfigAModule = isModule(types); - if (isModule && isComponent) { + if (isConfigAModule && isConfigAComponent) { throw new Error( 'Found type extending "TurboModule" and exported "codegenNativeComponent" declaration in one file. Split them into separated files.', ); } - if (isModule) { + if (isConfigAModule) { return 'module'; - } else if (isComponent) { + } else if (isConfigAComponent) { return 'component'; } else { throw new Error( - `Default export for module specified incorrectly. It should containts - either type extending "TurboModule" or "codegenNativeComponent".`, + 'File neither contains a module declaration, nor a component declaration. ' + + 'For module declarations, please make sure your file has an InterfaceDeclaration extending TurboModule. ' + + 'For component declarations, please make sure your file has a default export calling the codegenNativeComponent(...) macro.', ); } } diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap index 08193385e0a985..1fcaee4231a81e 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap @@ -12,12 +12,9 @@ exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_REA exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_UNNAMED_PARAMS 1`] = `"Unsupported type for getBool. Please provide a name for every parameter."`; -exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_EXTENDING_TURBO_MODULE 1`] = `"Found two types extending \\"TurboModule\\" is one file. Split them into separated files."`; +exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_EXTENDING_TURBO_MODULE 1`] = `"File contains declarations of more than one module: Spec, Spec2. Please declare exactly one module in this file."`; -exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_MODULES_EXPORTED_WITH_DEFAULT 1`] = ` -"Default export for module specified incorrectly. It should containts - either type extending \\"TurboModule\\" or \\"codegenNativeComponent\\"." -`; +exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_MODULES_EXPORTED_WITH_DEFAULT 1`] = `"File neither contains a module declaration, nor a component declaration. For module declarations, please make sure your file has an InterfaceDeclaration extending TurboModule. For component declarations, please make sure your file has a default export calling the codegenNativeComponent(...) macro."`; exports[`RN Codegen Flow Parser can generate fixture EMPTY_NATIVE_MODULE 1`] = ` Object { From 8c138baf4e1957622724a998c467c62524d53e44 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 11/52] Fix parser's buildSchema's return type Summary: `buildSchema` delegates to two other functions: `buildComponentSchema`, or `buildComponentSchema`. Both return have a return type of *required* `SchemaType`. Therefore, `buildSchema` can have a return type of `SchemaType`. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D23135499 fbshipit-source-id: f13db17549c93b965f372d9b68d06efc2a40c6cc --- .../react-native-codegen/src/parsers/flow/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index aeca0a0a1adeb0..c728418bde5a34 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -124,7 +124,7 @@ function getConfigType(ast, types: TypeDeclarations): 'module' | 'component' { } } -function buildSchema(contents: string, filename: ?string): ?SchemaType { +function buildSchema(contents: string, filename: ?string): SchemaType { const ast = flowParser.parse(contents); const types = getTypes(ast); @@ -142,20 +142,20 @@ function buildSchema(contents: string, filename: ?string): ?SchemaType { } } -function parseFile(filename: string): ?SchemaType { +function parseFile(filename: string): SchemaType { const contents = fs.readFileSync(filename, 'utf8'); return buildSchema(contents, filename); } -function parseModuleFixture(filename: string): ?SchemaType { +function parseModuleFixture(filename: string): SchemaType { const contents = fs.readFileSync(filename, 'utf8'); return buildSchema(contents, 'path/NativeSampleTurboModule.js'); } -function parseString(contents: string): ?SchemaType { - return buildSchema(contents); +function parseString(contents: string, filename: ?string): SchemaType { + return buildSchema(contents, filename); } module.exports = { From 78057729cebf2335edc0ff7520e91c6f15729e94 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 12/52] Clean up parsers/flow/modules/index.js Summary: Changes: - Adding type annotations, where possible - Delete unnecessary functions Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D23138227 fbshipit-source-id: b4b47492ddef49f496ed9fcb61ef1c000e3e8f18 --- .../src/parsers/flow/index.js | 4 +- .../src/parsers/flow/modules/index.js | 75 ++++++++----------- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index c728418bde5a34..5058a155bdc3d0 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -25,8 +25,10 @@ const {processModule} = require('./modules'); * declaration type. Unfortunately, we don't have those types, because flow-parser * generates them, and flow-parser is not type-safe. In the future, we should find * a way to get these types from our flow parser library. + * + * TODO(T71778680): Flow type AST Nodes */ -type TypeDeclarations = {|[declarationName: string]: $FlowFixMe|}; +export type TypeDeclarations = {|[declarationName: string]: $FlowFixMe|}; function getTypes(ast): TypeDeclarations { return ast.body.reduce((types, node) => { diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index d8f5e7d4cda476..8f9e81a9d0bec1 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -14,57 +14,48 @@ import type {NativeModuleShape} from '../../../CodegenSchema'; const {getAliases} = require('./aliases'); const {getMethods} = require('./methods'); -function getModuleProperties(types, interfaceName) { - if (types[interfaceName] && types[interfaceName].body) { - return types[interfaceName].body.properties; - } - throw new Error( - `Interface properties for "${interfaceName}" has been specified incorrectly.`, +import type {TypeDeclarations} from '../index'; + +// TODO(T71778680): Flow type AST Nodes +function getModuleProperties( + types: TypeDeclarations, +): $ReadOnlyArray<$FlowFixMe> { + const declaredModuleNames: Array = Object.keys(types).filter( + (typeName: string) => { + const declaration = types[typeName]; + return ( + declaration.type === 'InterfaceDeclaration' && + declaration.extends.length === 1 && + declaration.extends[0].type === 'InterfaceExtends' && + declaration.extends[0].id.name === 'TurboModule' + ); + }, ); -} -function findInterfaceName(types) { - return Object.keys(types) - .map(typeName => types[typeName]) - .filter( - type => - type.extends && - type.extends[0] && - type.extends[0].id.name === 'TurboModule', - )[0].id.name; + return types[declaredModuleNames[0]].body.properties; } -function findAliasNames(types) { +// TODO(T71778680): Flow type AST Nodes +function getModuleAliases( + types: TypeDeclarations, + aliasNames, +): $ReadOnlyArray<{[aliasName: string]: $FlowFixMe}> { return Object.keys(types) - .map(typeName => types[typeName]) - .filter( - type => - type.type && - type.type === 'TypeAlias' && - type.right && - type.right.type === 'ObjectTypeAnnotation', - ) - .map(type => type.id.name); -} - -function getModuleAliases(types, aliasNames) { - return aliasNames.map(aliasName => { - if (types[aliasName] && types[aliasName].right) { - return {[aliasName]: types[aliasName].right}; - } - throw new Error( - `Interface properties for "${aliasName}" has been specified incorrectly.`, - ); - }); + .filter((typeName: string) => { + const declaration = types[typeName]; + return ( + declaration.type === 'TypeAlias' && + declaration.right.type === 'ObjectTypeAnnotation' + ); + }) + .map(aliasName => ({[aliasName]: types[aliasName].right})); } -function processModule(types: $FlowFixMe): NativeModuleShape { - const interfaceName = findInterfaceName(types); - const moduleProperties = getModuleProperties(types, interfaceName); +function processModule(types: TypeDeclarations): NativeModuleShape { + const moduleProperties = getModuleProperties(types); const properties = getMethods(moduleProperties, types); - const aliasNames = findAliasNames(types); - const moduleAliases = getModuleAliases(types, aliasNames); + const moduleAliases = getModuleAliases(types); const aliases = getAliases(moduleAliases, types); return {aliases, properties}; From 747f493febfb8e6ea6e1e5ada6406ca4b3931519 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 13/52] Colocate alias/method generation logic Summary: ## Changes - Generating the aliases was split over `parsers/flow/modules/index.js`, and `parsers/flow/modules/aliases.js`. I moved everything to the latter file. - Generating methods was split over `parsers/flow/modules/index.js` and `parsers/flow/modules/methods.js`. I moved everything to the latter file. - More type-safety Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23143382 fbshipit-source-id: e11b76bee7917a7db37ae7f1af64da5f046c5d1e --- .../react-native-codegen/src/CodegenSchema.js | 8 +- .../src/parsers/flow/components/commands.js | 6 +- .../src/parsers/flow/components/extends.js | 8 +- .../src/parsers/flow/components/props.js | 13 ++-- .../src/parsers/flow/index.js | 16 +--- .../src/parsers/flow/modules/aliases.js | 75 +++++++------------ .../src/parsers/flow/modules/index.js | 47 +----------- .../src/parsers/flow/modules/methods.js | 32 ++++++-- .../src/parsers/flow/modules/properties.js | 6 +- .../src/parsers/flow/utils.js | 13 +++- 10 files changed, 94 insertions(+), 130 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index f827018f020103..36e08a6bb6eb58 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -261,10 +261,16 @@ export type SchemaType = $ReadOnly<{| */ export type NativeModuleShape = $ReadOnly<{| // We only support aliases to Objects - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, + aliases: NativeModuleAliasMap, properties: $ReadOnlyArray, |}>; +export type NativeModuleAliasMap = $ReadOnly<{ + [aliasName: string]: NativeModuleAlias, +}>; + +export type NativeModuleAlias = ObjectTypeAliasTypeShape; + export type ObjectTypeAliasTypeShape = $ReadOnly<{| type: 'ObjectTypeAnnotation', properties: $ReadOnlyArray, diff --git a/packages/react-native-codegen/src/parsers/flow/components/commands.js b/packages/react-native-codegen/src/parsers/flow/components/commands.js index 769039be7a074d..92aef0a2ad0b18 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/commands.js +++ b/packages/react-native-codegen/src/parsers/flow/components/commands.js @@ -11,13 +11,13 @@ 'use strict'; import type {CommandTypeShape} from '../../../CodegenSchema.js'; -import type {TypeMap} from '../utils.js'; +import type {TypeDeclarationMap} from '../utils.js'; const {getValueFromTypes} = require('../utils.js'); type EventTypeAST = Object; -function buildCommandSchema(property, types: TypeMap) { +function buildCommandSchema(property, types: TypeDeclarationMap) { const name = property.key.name; const optional = property.optional; const value = getValueFromTypes(property.value, types); @@ -98,7 +98,7 @@ function buildCommandSchema(property, types: TypeMap) { function getCommands( commandTypeAST: $ReadOnlyArray, - types: TypeMap, + types: TypeDeclarationMap, ): $ReadOnlyArray { return commandTypeAST .filter(property => property.type === 'ObjectTypeProperty') diff --git a/packages/react-native-codegen/src/parsers/flow/components/extends.js b/packages/react-native-codegen/src/parsers/flow/components/extends.js index 77081974a30a69..7d5e899b80828b 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/extends.js +++ b/packages/react-native-codegen/src/parsers/flow/components/extends.js @@ -11,9 +11,9 @@ 'use strict'; import type {ExtendsPropsShape} from '../../../CodegenSchema.js'; -import type {TypeMap} from '../utils.js'; +import type {TypeDeclarationMap} from '../utils.js'; -function extendsForProp(prop: PropsAST, types: TypeMap) { +function extendsForProp(prop: PropsAST, types: TypeDeclarationMap) { if (!prop.argument) { console.log('null', prop); } @@ -38,7 +38,7 @@ function extendsForProp(prop: PropsAST, types: TypeMap) { function removeKnownExtends( typeDefinition: $ReadOnlyArray, - types: TypeMap, + types: TypeDeclarationMap, ): $ReadOnlyArray { return typeDefinition.filter( prop => @@ -52,7 +52,7 @@ type PropsAST = Object; function getExtendsProps( typeDefinition: $ReadOnlyArray, - types: TypeMap, + types: TypeDeclarationMap, ): $ReadOnlyArray { return typeDefinition .filter(prop => prop.type === 'ObjectTypeSpreadProperty') diff --git a/packages/react-native-codegen/src/parsers/flow/components/props.js b/packages/react-native-codegen/src/parsers/flow/components/props.js index 9b549ac2337acd..50e887bcd93b9e 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/props.js +++ b/packages/react-native-codegen/src/parsers/flow/components/props.js @@ -13,9 +13,12 @@ const {getValueFromTypes} = require('../utils.js'); import type {PropTypeShape} from '../../../CodegenSchema.js'; -import type {TypeMap} from '../utils.js'; +import type {TypeDeclarationMap} from '../utils.js'; -function getPropProperties(propsTypeName: string, types: TypeMap): $FlowFixMe { +function getPropProperties( + propsTypeName: string, + types: TypeDeclarationMap, +): $FlowFixMe { const typeAlias = types[propsTypeName]; try { return typeAlias.right.typeParameters.params[0].properties; @@ -321,7 +324,7 @@ function getTypeAnnotation( } } -function buildPropSchema(property, types: TypeMap): ?PropTypeShape { +function buildPropSchema(property, types: TypeDeclarationMap): ?PropTypeShape { const name = property.key.name; const value = getValueFromTypes(property.value, types); @@ -426,7 +429,7 @@ function verifyPropNotAlreadyDefined( function flattenProperties( typeDefinition: $ReadOnlyArray, - types: TypeMap, + types: TypeDeclarationMap, ) { return typeDefinition .map(property => { @@ -456,7 +459,7 @@ function flattenProperties( function getProps( typeDefinition: $ReadOnlyArray, - types: TypeMap, + types: TypeDeclarationMap, ): $ReadOnlyArray { return flattenProperties(typeDefinition, types) .map(property => buildPropSchema(property, types)) diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index 5058a155bdc3d0..9e8bdb2603ae4d 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -20,17 +20,9 @@ const {buildComponentSchema} = require('./components/schema'); const {processComponent} = require('./components'); const {processModule} = require('./modules'); -/** - * This FlowFixMe is supposed to refer to an InterfaceDeclaration or TypeAlias - * declaration type. Unfortunately, we don't have those types, because flow-parser - * generates them, and flow-parser is not type-safe. In the future, we should find - * a way to get these types from our flow parser library. - * - * TODO(T71778680): Flow type AST Nodes - */ -export type TypeDeclarations = {|[declarationName: string]: $FlowFixMe|}; +import type {TypeDeclarationMap} from './utils'; -function getTypes(ast): TypeDeclarations { +function getTypes(ast): TypeDeclarationMap { return ast.body.reduce((types, node) => { if (node.type === 'ExportNamedDeclaration' && node.exportKind === 'type') { if ( @@ -75,7 +67,7 @@ function isComponent(ast) { ); } -function isModule(types: TypeDeclarations) { +function isModule(types: TypeDeclarationMap) { const declaredModuleNames: Array = Object.keys(types).filter( (typeName: string) => { const declaration = types[typeName]; @@ -103,7 +95,7 @@ function isModule(types: TypeDeclarations) { return true; } -function getConfigType(ast, types: TypeDeclarations): 'module' | 'component' { +function getConfigType(ast, types: TypeDeclarationMap): 'module' | 'component' { const isConfigAComponent = isComponent(ast); const isConfigAModule = isModule(types); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/aliases.js b/packages/react-native-codegen/src/parsers/flow/modules/aliases.js index 7c55e4d9ff61a6..b21326d8e51110 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/aliases.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/aliases.js @@ -10,59 +10,36 @@ 'use strict'; -import type {ObjectTypeAliasTypeShape} from '../../../CodegenSchema.js'; - -import type {TypeMap} from '../utils.js'; +import type {NativeModuleAliasMap} from '../../../CodegenSchema.js'; +import type {TypeDeclarationMap} from '../utils'; const {getObjectProperties} = require('./properties'); -// $FlowFixMe there's no flowtype for ASTs -type MethodAST = Object; - -function getAliases( - typeDefinition: $ReadOnlyArray, - types: TypeMap, -): $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}> { - const aliases = {}; - typeDefinition.map(moduleAlias => { - const aliasName = Object.keys(moduleAlias)[0]; - const typeAnnotation = moduleAlias[Object.keys(moduleAlias)[0]]; - - switch (typeAnnotation.type) { - case 'ObjectTypeAnnotation': - aliases[aliasName] = { +function getAliases(types: TypeDeclarationMap): NativeModuleAliasMap { + const typeNames: Array = Object.keys(types); + return typeNames + .filter((typeName: string) => { + const declaration = types[typeName]; + return ( + declaration.type === 'TypeAlias' && + declaration.right.type === 'ObjectTypeAnnotation' + ); + }) + .reduce((aliases: NativeModuleAliasMap, aliasName: string) => { + const alias = types[aliasName]; + return { + ...aliases, + [aliasName]: { type: 'ObjectTypeAnnotation', - ...(typeAnnotation.properties && { - properties: getObjectProperties( - aliasName, - {properties: typeAnnotation.properties}, - aliasName, - types, - ), - }), - }; - return; - case 'GenericTypeAnnotation': - if (typeAnnotation.id.name && typeAnnotation.id.name !== '') { - aliases[aliasName] = { - type: 'TypeAliasTypeAnnotation', - name: typeAnnotation.id.name, - }; - return; - } else { - throw new Error( - `Cannot use "${typeAnnotation.type}" type annotation for "${aliasName}": must specify a type alias name`, - ); - } - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error( - `Unknown prop type, found "${typeAnnotation.type}" in "${aliasName}"`, - ); - } - }); - return aliases; + properties: getObjectProperties( + aliasName, + {properties: alias.right.properties}, + aliasName, + types, + ), + }, + }; + }, ({}: NativeModuleAliasMap)); } module.exports = { diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 8f9e81a9d0bec1..1b52cb7da220d2 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -14,50 +14,11 @@ import type {NativeModuleShape} from '../../../CodegenSchema'; const {getAliases} = require('./aliases'); const {getMethods} = require('./methods'); -import type {TypeDeclarations} from '../index'; - -// TODO(T71778680): Flow type AST Nodes -function getModuleProperties( - types: TypeDeclarations, -): $ReadOnlyArray<$FlowFixMe> { - const declaredModuleNames: Array = Object.keys(types).filter( - (typeName: string) => { - const declaration = types[typeName]; - return ( - declaration.type === 'InterfaceDeclaration' && - declaration.extends.length === 1 && - declaration.extends[0].type === 'InterfaceExtends' && - declaration.extends[0].id.name === 'TurboModule' - ); - }, - ); - - return types[declaredModuleNames[0]].body.properties; -} - -// TODO(T71778680): Flow type AST Nodes -function getModuleAliases( - types: TypeDeclarations, - aliasNames, -): $ReadOnlyArray<{[aliasName: string]: $FlowFixMe}> { - return Object.keys(types) - .filter((typeName: string) => { - const declaration = types[typeName]; - return ( - declaration.type === 'TypeAlias' && - declaration.right.type === 'ObjectTypeAnnotation' - ); - }) - .map(aliasName => ({[aliasName]: types[aliasName].right})); -} - -function processModule(types: TypeDeclarations): NativeModuleShape { - const moduleProperties = getModuleProperties(types); - const properties = getMethods(moduleProperties, types); - - const moduleAliases = getModuleAliases(types); - const aliases = getAliases(moduleAliases, types); +import type {TypeDeclarationMap} from '../utils'; +function processModule(types: TypeDeclarationMap): NativeModuleShape { + const properties = getMethods(types); + const aliases = getAliases(types); return {aliases, properties}; } diff --git a/packages/react-native-codegen/src/parsers/flow/modules/methods.js b/packages/react-native-codegen/src/parsers/flow/modules/methods.js index 2445b5d38e551d..17764051194e23 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/methods.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/methods.js @@ -16,12 +16,13 @@ import type { FunctionTypeAnnotationReturn, } from '../../../CodegenSchema.js'; -import type {ASTNode, TypeMap} from '../utils.js'; +import type {ASTNode, TypeDeclarationMap} from '../utils.js'; const {getValueFromTypes} = require('../utils.js'); const { getElementTypeForArrayOrObject, getObjectProperties, } = require('./properties'); +const invariant = require('invariant'); // $FlowFixMe there's no flowtype for ASTs type MethodAST = Object; @@ -29,7 +30,7 @@ type MethodAST = Object; function getTypeAnnotationForParam( name: string, paramAnnotation: ASTNode, - types: TypeMap, + types: TypeDeclarationMap, ): FunctionTypeAnnotationParam { let param = paramAnnotation; if (param.name === null) { @@ -188,7 +189,7 @@ function getTypeAnnotationForParam( function getReturnTypeAnnotation( methodName: string, returnType, - types: TypeMap, + types: TypeDeclarationMap, ): FunctionTypeAnnotationReturn { let typeAnnotation = getValueFromTypes(returnType, types); let nullable = false; @@ -315,7 +316,7 @@ function getReturnTypeAnnotation( function buildMethodSchema( property: MethodAST, - types: TypeMap, + types: TypeDeclarationMap, ): NativeModuleMethodTypeShape { const name: string = property.key.name; const value = getValueFromTypes(property.value, types); @@ -345,10 +346,27 @@ function buildMethodSchema( } function getMethods( - typeDefinition: $ReadOnlyArray, - types: TypeMap, + types: TypeDeclarationMap, ): $ReadOnlyArray { - return typeDefinition + const moduleInterfaceNames = Object.keys(types).filter((typeName: string) => { + const declaration = types[typeName]; + return ( + declaration.type === 'InterfaceDeclaration' && + declaration.extends.length === 1 && + declaration.extends[0].type === 'InterfaceExtends' && + declaration.extends[0].id.name === 'TurboModule' + ); + }); + + invariant( + moduleInterfaceNames.length === 1, + 'There must be exactly one module declaration per file', + ); + + const [moduleInterfaceName] = moduleInterfaceNames; + + const declaration = types[moduleInterfaceName]; + return declaration.body.properties .filter(property => property.type === 'ObjectTypeProperty') .map(property => buildMethodSchema(property, types)) .filter(Boolean); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/properties.js b/packages/react-native-codegen/src/parsers/flow/modules/properties.js index f1e8c51e7fe443..b1c1bbb11ed16c 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/properties.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/properties.js @@ -16,14 +16,14 @@ import type { TypeAliasTypeAnnotation, } from '../../../CodegenSchema.js'; -import type {ASTNode, TypeMap} from '../utils.js'; +import type {ASTNode, TypeDeclarationMap} from '../utils.js'; const {getValueFromTypes} = require('../utils.js'); function getObjectProperties( name: string, objectParam: ASTNode, paramName: string, - types: TypeMap, + types: TypeDeclarationMap, ): $ReadOnlyArray { return objectParam.properties.map(objectTypeProperty => { let optional = objectTypeProperty.optional; @@ -53,7 +53,7 @@ function getElementTypeForArrayOrObject( name: string, arrayParam: ASTNode, paramName: string, - types: TypeMap, + types: TypeDeclarationMap, ): | FunctionTypeAnnotationParamTypeAnnotation | TypeAliasTypeAnnotation diff --git a/packages/react-native-codegen/src/parsers/flow/utils.js b/packages/react-native-codegen/src/parsers/flow/utils.js index 663b6b90bb941a..7e1e57f2989c7f 100644 --- a/packages/react-native-codegen/src/parsers/flow/utils.js +++ b/packages/react-native-codegen/src/parsers/flow/utils.js @@ -10,13 +10,20 @@ 'use strict'; -// $FlowFixMe there's no flowtype for ASTs -export type TypeMap = $ReadOnly<{|[name: string]: Object|}>; +/** + * This FlowFixMe is supposed to refer to an InterfaceDeclaration or TypeAlias + * declaration type. Unfortunately, we don't have those types, because flow-parser + * generates them, and flow-parser is not type-safe. In the future, we should find + * a way to get these types from our flow parser library. + * + * TODO(T71778680): Flow type AST Nodes + */ +export type TypeDeclarationMap = {|[declarationName: string]: $FlowFixMe|}; // $FlowFixMe there's no flowtype for ASTs export type ASTNode = Object; -function getValueFromTypes(value: ASTNode, types: TypeMap): ASTNode { +function getValueFromTypes(value: ASTNode, types: TypeDeclarationMap): ASTNode { if (value.type === 'GenericTypeAnnotation' && types[value.id.name]) { return getValueFromTypes(types[value.id.name].right, types); } From f9ea52574ebec71e2c39bf486b979c243512486b Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 14/52] Cleanup buildMethodSchema and introduce nullable methods Summary: ## Changes - Started doing cleanup under `/parsers/flow/modules/methods.js` - Rename `NativeModuleMethodTypeShape` -> `NativeModulePropertyShape` - Moved optional property from `FunctionTypeAnnotation` to the `NativeModulePropertyShape` - Introduced a nullable property inside what was once `FunctionTypeAnnotation`. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23146050 fbshipit-source-id: 2fe97bb9c0736242682133e4923131a54bbea54b --- .../react-native-codegen/src/CodegenSchema.js | 17 ++-- .../modules/GenerateModuleJavaSpec.js | 4 +- .../modules/__test_fixtures__/fixtures.js | 96 ++++++++++++------- .../__snapshots__/module-parser-test.js.snap | 93 ++++++++++++------ .../src/parsers/flow/modules/methods.js | 41 +++++--- 5 files changed, 165 insertions(+), 86 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 36e08a6bb6eb58..0e2a5ec60dca4a 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -262,7 +262,7 @@ export type SchemaType = $ReadOnly<{| export type NativeModuleShape = $ReadOnly<{| // We only support aliases to Objects aliases: NativeModuleAliasMap, - properties: $ReadOnlyArray, + properties: $ReadOnlyArray, |}>; export type NativeModuleAliasMap = $ReadOnly<{ @@ -276,16 +276,15 @@ export type ObjectTypeAliasTypeShape = $ReadOnly<{| properties: $ReadOnlyArray, |}>; -export type NativeModuleMethodTypeShape = $ReadOnly<{| +export type NativeModulePropertyShape = $ReadOnly<{| name: string, - typeAnnotation: FunctionTypeAnnotation, -|}>; - -export type FunctionTypeAnnotation = $ReadOnly<{| - type: 'FunctionTypeAnnotation', - params: $ReadOnlyArray, - returnTypeAnnotation: FunctionTypeAnnotationReturn, optional: boolean, + typeAnnotation: $ReadOnly<{| + type: 'FunctionTypeAnnotation', + params: $ReadOnlyArray, + returnTypeAnnotation: FunctionTypeAnnotationReturn, + nullable: boolean, + |}>, |}>; export type FunctionTypeAnnotationReturn = diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 5054146e4ffc56..43937022e4f52c 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -13,7 +13,7 @@ import type { FunctionTypeAnnotationParam, FunctionTypeAnnotationReturn, - NativeModuleMethodTypeShape, + NativeModulePropertyShape, ObjectTypeAliasTypeShape, SchemaType, } from '../../CodegenSchema'; @@ -156,7 +156,7 @@ function translateFunctionReturnTypeToJavaType( // Build special-cased runtime check for getConstants(). function buildGetConstantsMethod( - method: NativeModuleMethodTypeShape, + method: NativeModulePropertyShape, imports: Set, ): string { if ( diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index cea663c8b1b425..1c5a3b9127da42 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -34,6 +34,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -64,11 +65,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { ], }, params: [], - optional: false, + nullable: false, }, }, { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -76,11 +78,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, { name: 'getBool', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -96,11 +99,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getNumber', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -116,11 +120,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getString', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -136,11 +141,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getArray', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -162,11 +168,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getObject', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -182,11 +189,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getRootTag', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -204,11 +212,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getValue', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -238,11 +247,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getValueWithCallback', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -258,11 +268,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getValueWithPromise', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -278,7 +289,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -297,6 +308,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { properties: [ { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -304,7 +316,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -314,6 +326,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { properties: [ { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -321,7 +334,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -340,6 +353,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { properties: [ { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -347,7 +361,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -361,6 +375,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -369,11 +384,12 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { properties: [], }, params: [], - optional: false, + nullable: false, }, }, { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -381,7 +397,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -400,6 +416,7 @@ const COMPLEX_OBJECTS: SchemaType = { properties: [ { name: 'difficult', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -491,11 +508,12 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'optionals', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -567,11 +585,12 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'optionalMethod', + optional: true, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -617,11 +636,12 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: true, + nullable: true, }, }, { name: 'getArrays', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -698,7 +718,7 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -806,6 +826,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -814,11 +835,12 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { properties: [], }, params: [], - optional: false, + nullable: false, }, }, { name: 'cropImage', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -835,7 +857,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -1092,6 +1114,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1100,11 +1123,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [], }, params: [], - optional: false, + nullable: false, }, }, { name: 'getPhotos', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1121,11 +1145,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'saveToCameraRoll', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1148,11 +1173,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'deletePhotos', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1171,7 +1197,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -1185,6 +1211,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [ { name: 'openCameraDialog', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1230,7 +1257,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -1350,6 +1377,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [ { name: 'reportFatalException', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1383,11 +1411,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'reportSoftException', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1421,11 +1450,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'reportException', + optional: true, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1442,11 +1472,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: true, + nullable: true, }, }, { name: 'updateExceptionMessage', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1480,11 +1511,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'dismissRedbox', + optional: true, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1492,7 +1524,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: true, + nullable: true, }, }, ], diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap index 1fcaee4231a81e..54ae74f6566db6 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap @@ -75,8 +75,9 @@ Object { "properties": Array [ Object { "name": "getNumber", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -95,8 +96,9 @@ Object { }, Object { "name": "getVoid", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -107,8 +109,9 @@ Object { }, Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "a", @@ -139,8 +142,9 @@ Object { }, Object { "name": "getStringFromAlias", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "a", @@ -176,8 +180,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -218,8 +223,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -256,8 +262,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -282,8 +289,9 @@ Object { }, Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -324,8 +332,9 @@ Object { "properties": Array [ Object { "name": "passBool", + "optional": true, "typeAnnotation": Object { - "optional": true, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -344,8 +353,9 @@ Object { }, Object { "name": "passNumber", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -364,8 +374,9 @@ Object { }, Object { "name": "passString", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -384,8 +395,9 @@ Object { }, Object { "name": "passStringish", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -420,8 +432,9 @@ Object { "properties": Array [ Object { "name": "getValueWithCallback", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "callback", @@ -456,8 +469,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -516,8 +530,9 @@ Object { "properties": Array [ Object { "name": "getObject", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -572,8 +587,9 @@ Object { }, Object { "name": "getReadOnlyObject", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -628,8 +644,9 @@ Object { }, Object { "name": "getObject2", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -657,8 +674,9 @@ Object { }, Object { "name": "getObjectInArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -732,8 +750,9 @@ Object { "properties": Array [ Object { "name": "getConstants", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -834,8 +853,9 @@ Object { "properties": Array [ Object { "name": "getInt", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -854,8 +874,9 @@ Object { }, Object { "name": "getFloat", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -924,8 +945,9 @@ Object { "properties": Array [ Object { "name": "foo1", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "x", @@ -946,8 +968,9 @@ Object { }, Object { "name": "foo2", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "x", @@ -983,8 +1006,9 @@ Object { "properties": Array [ Object { "name": "voidFunc", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -1032,8 +1056,9 @@ Object { "properties": Array [ Object { "name": "getConstants", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1063,8 +1088,9 @@ Object { }, Object { "name": "getConstants2", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1123,8 +1149,9 @@ Object { "properties": Array [ Object { "name": "getValueWithPromise", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1135,8 +1162,9 @@ Object { }, Object { "name": "getValueWithPromiseDefinedSomewhereElse", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1147,8 +1175,9 @@ Object { }, Object { "name": "getValueWithPromiseObjDefinedSomewhereElse", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1175,8 +1204,9 @@ Object { "properties": Array [ Object { "name": "getRootTag", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "rootTag", @@ -1213,8 +1243,9 @@ Object { "properties": Array [ Object { "name": "getObject", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "o", diff --git a/packages/react-native-codegen/src/parsers/flow/modules/methods.js b/packages/react-native-codegen/src/parsers/flow/modules/methods.js index 17764051194e23..e3773c01215874 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/methods.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/methods.js @@ -11,7 +11,7 @@ 'use strict'; import type { - NativeModuleMethodTypeShape, + NativeModulePropertyShape, FunctionTypeAnnotationParam, FunctionTypeAnnotationReturn, } from '../../../CodegenSchema.js'; @@ -24,9 +24,6 @@ const { } = require('./properties'); const invariant = require('invariant'); -// $FlowFixMe there's no flowtype for ASTs -type MethodAST = Object; - function getTypeAnnotationForParam( name: string, paramAnnotation: ASTNode, @@ -315,16 +312,35 @@ function getReturnTypeAnnotation( } function buildMethodSchema( - property: MethodAST, + // TODO(T71778680): This is an ObjectTypeProperty containing either: + // - a FunctionTypeAnnotation or GenericTypeAnnotation + // - a NullableTypeAnnoation containing a FunctionTypeAnnotation or GenericTypeAnnotation + // Flow type this node + property: $FlowFixMe, types: TypeDeclarationMap, -): NativeModuleMethodTypeShape { - const name: string = property.key.name; - const value = getValueFromTypes(property.value, types); +): NativeModulePropertyShape { + let nullable = false; + let {key, value} = property; + + // Unwrap Nullable types + if (value.type === 'NullableTypeAnnotation') { + nullable = true; + value = value.typeAnnotation; + } + + const name: string = key.name; + + // Resolve type aliases + if (value.type === 'GenericTypeAnnotation') { + value = getValueFromTypes(value, types); + } + if (value.type !== 'FunctionTypeAnnotation') { throw new Error( `Only methods are supported as module properties. Found ${value.type} in ${property.key.name}`, ); } + const params = value.params.map(param => getTypeAnnotationForParam(name, param, types), ); @@ -334,20 +350,22 @@ function buildMethodSchema( value.returnType, types, ); + return { name, + optional: property.optional, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation, params, - optional: property.optional, + nullable, }, }; } function getMethods( types: TypeDeclarationMap, -): $ReadOnlyArray { +): $ReadOnlyArray { const moduleInterfaceNames = Object.keys(types).filter((typeName: string) => { const declaration = types[typeName]; return ( @@ -368,8 +386,7 @@ function getMethods( const declaration = types[moduleInterfaceName]; return declaration.body.properties .filter(property => property.type === 'ObjectTypeProperty') - .map(property => buildMethodSchema(property, types)) - .filter(Boolean); + .map(property => buildMethodSchema(property, types)); } module.exports = { From 2d19037041defb765a80bc417215229ff120ba3a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 15/52] Rewrite Flow module parser Summary: This diff: 1. Simplifies the NativeModule schema Flow types. 2. Simplifies the NativeModule Flow parser, to accomodate the modified schema, and to reduce code duplication. **Notes:** - If the parser detects an unrecognized type within the context of parsing an Array's element type, it'll omit the `elementType` property of the `ArrayTypeAnnotation`. Details: T72031674. **Rationale:** Basically, when an array element type is supported, we use it in our generators. When it's unsupported, we ignore it. In the unsupported case, there's no point in trying to parse the Array element type, which is why I decided to omit the `elementType` property. Ideally, our NativeModule specs would never use unsupported types, in any context. This would allow us to always parse and use the elementType. However, that seems like a it could be a hefty migration: we have > 400 specs. Since, this isn't a battle we need to fight right now, I left a TODO at the relevant lines instead. - The legacy codegen would generate structs for each object literal type in the file. In this re-implementation of the parser, I only insert into the aliases array when we detect a usage of a type-alias to an ObjectLiteral type annotation. With this decision, we won't be able to generate these unnecessary structs. This is good because we get rid of dead code. It's bad because it might make our migration to this codegen bit more difficult. [WARNING] This diff produces flow failures that will be addressed in subsequent diffs. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D23201387 fbshipit-source-id: 55ce0df925a8bae0e7d5bb2a9b63167607eba461 --- .../NativeOptionalObjectTurboModule.js | 1 - .../react-native-codegen/src/CodegenSchema.js | 160 ++++--- .../src/parsers/flow/components/index.js | 4 +- .../src/parsers/flow/components/schema.js | 4 +- .../src/parsers/flow/index.js | 12 +- .../modules/__test_fixtures__/fixtures.js | 3 +- .../__snapshots__/module-parser-test.js.snap | 189 ++++++-- .../src/parsers/flow/modules/aliases.js | 47 -- .../src/parsers/flow/modules/errors.js | 112 +++++ .../src/parsers/flow/modules/index.js | 415 +++++++++++++++++- .../src/parsers/flow/modules/methods.js | 394 ----------------- .../src/parsers/flow/modules/properties.js | 159 ------- .../src/parsers/flow/modules/schema.js | 8 +- .../src/parsers/flow/utils.js | 42 ++ 14 files changed, 797 insertions(+), 753 deletions(-) delete mode 100644 packages/react-native-codegen/src/parsers/flow/modules/aliases.js create mode 100644 packages/react-native-codegen/src/parsers/flow/modules/errors.js delete mode 100644 packages/react-native-codegen/src/parsers/flow/modules/methods.js delete mode 100644 packages/react-native-codegen/src/parsers/flow/modules/properties.js diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeOptionalObjectTurboModule.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeOptionalObjectTurboModule.js index b697ab954dd573..02784457c3bdfb 100644 --- a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeOptionalObjectTurboModule.js +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeOptionalObjectTurboModule.js @@ -17,7 +17,6 @@ export interface Spec extends TurboModule { +getConstants: () => {| D?: ?boolean, A?: Array, - G?: any, E?: ?{| D?: ?boolean, E?: ?{| diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 0e2a5ec60dca4a..425662967a2c6e 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -248,7 +248,7 @@ export type SchemaType = $ReadOnly<{| [module: string]: $ReadOnly<{| components?: $ReadOnly<{[component: string]: ComponentShape, ...}>, nativeModules?: $ReadOnly<{ - [nativeModule: string]: NativeModuleShape, + [nativeModule: string]: NativeModuleSchema, ..., }>, |}>, @@ -259,121 +259,119 @@ export type SchemaType = $ReadOnly<{| /** * NativeModule Types */ -export type NativeModuleShape = $ReadOnly<{| +export type NativeModuleSchema = $ReadOnly<{| // We only support aliases to Objects - aliases: NativeModuleAliasMap, - properties: $ReadOnlyArray, + aliases: $ReadOnly, + properties: $ReadOnlyArray, |}>; -export type NativeModuleAliasMap = $ReadOnly<{ - [aliasName: string]: NativeModuleAlias, -}>; +export type NativeModuleAliasMap = { + [aliasName: string]: NativeModuleObjectTypeAnnotation, +}; -export type NativeModuleAlias = ObjectTypeAliasTypeShape; - -export type ObjectTypeAliasTypeShape = $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, +export type NativeModulePropertySchema = $ReadOnly<{| + name: string, + optional: boolean, + typeAnnotation: NativeModuleFunctionTypeAnnotation, |}>; -export type NativeModulePropertyShape = $ReadOnly<{| +export type NativeModuleMethodParamSchema = $ReadOnly<{| name: string, optional: boolean, - typeAnnotation: $ReadOnly<{| - type: 'FunctionTypeAnnotation', - params: $ReadOnlyArray, - returnTypeAnnotation: FunctionTypeAnnotationReturn, - nullable: boolean, - |}>, + typeAnnotation: NativeModuleParamTypeAnnotation, +|}>; + +export type NativeModuleFunctionTypeAnnotation = $ReadOnly<{| + type: 'FunctionTypeAnnotation', + params: $ReadOnlyArray, + returnTypeAnnotation: NativeModuleReturnTypeAnnotation, + nullable: boolean, +|}>; + +export type NativeModuleObjectTypeAnnotation = $ReadOnly<{| + type: 'ObjectTypeAnnotation', + properties: $ReadOnlyArray< + $ReadOnly<{| + optional: boolean, + name: string, + typeAnnotation: NativeModuleParamTypeAnnotation, + |}>, + >, + nullable: boolean, |}>; -export type FunctionTypeAnnotationReturn = +export type NativeModuleBaseTypeAnnotation = | $ReadOnly<{| + type: 'StringTypeAnnotation', nullable: boolean, - type: - | 'GenericPromiseTypeAnnotation' - | 'VoidTypeAnnotation' - | PrimitiveTypeAnnotationType, |}> | $ReadOnly<{| + type: 'NumberTypeAnnotation', nullable: boolean, - type: 'ReservedFunctionValueTypeAnnotation', - name: ReservedFunctionValueTypeName, |}> | $ReadOnly<{| + type: 'Int32TypeAnnotation', nullable: boolean, - type: 'ArrayTypeAnnotation', - elementType: ?FunctionTypeAnnotationReturnArrayElementType, |}> | $ReadOnly<{| + type: 'DoubleTypeAnnotation', nullable: boolean, - type: 'ObjectTypeAnnotation', - properties: ?$ReadOnlyArray, |}> | $ReadOnly<{| + type: 'FloatTypeAnnotation', nullable: boolean, - type: 'TypeAliasTypeAnnotation', - name: string, - |}>; - -export type FunctionTypeAnnotationReturnArrayElementType = - | FunctionTypeAnnotationParamTypeAnnotation // TODO: What does FunctionTypeAnnotationParamTypeAnnotation have to do with function returns? - | TypeAliasTypeAnnotation; - -export type TypeAliasTypeAnnotation = $ReadOnly<{| - type: 'TypeAliasTypeAnnotation', - name: string, -|}>; - -export type FunctionTypeAnnotationParam = $ReadOnly<{| - nullable: boolean, - name: string, - typeAnnotation: - | FunctionTypeAnnotationParamTypeAnnotation - | TypeAliasTypeAnnotation, -|}>; - -export type FunctionTypeAnnotationParamTypeAnnotation = + |}> + | $ReadOnly<{| + type: 'BooleanTypeAnnotation', + nullable: boolean, + |}> | $ReadOnly<{| - type: - | 'AnyTypeAnnotation' - | 'FunctionTypeAnnotation' - | PrimitiveTypeAnnotationType, + type: 'GenericObjectTypeAnnotation', + nullable: boolean, |}> | $ReadOnly<{| type: 'ReservedFunctionValueTypeAnnotation', name: ReservedFunctionValueTypeName, + nullable: boolean, |}> | $ReadOnly<{| type: 'ArrayTypeAnnotation', - elementType: - | ?FunctionTypeAnnotationParamTypeAnnotation - | ?TypeAliasTypeAnnotation, + /** + * TODO(T72031674): Migrate all our NativeModule specs to not use + * invalid Array ElementTypes. Then, make the elementType required. + */ + elementType?: NativeModuleBaseTypeAnnotation, + nullable: boolean, |}> | $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: ?$ReadOnlyArray, + type: 'TypeAliasTypeAnnotation', + name: string, + nullable: boolean, + |}> + | NativeModuleObjectTypeAnnotation; + +export type NativeModuleParamOnlyTypeAnnotation = NativeModuleFunctionTypeAnnotation; +export type NativeModuleReturnOnlyTypeAnnotation = + | $ReadOnly<{| + nullable: boolean, + type: 'GenericPromiseTypeAnnotation', + |}> + | $ReadOnly<{| + nullable: boolean, + type: 'VoidTypeAnnotation', |}>; -export type PrimitiveTypeAnnotationType = - | 'StringTypeAnnotation' - | 'NumberTypeAnnotation' - | 'Int32TypeAnnotation' - | 'DoubleTypeAnnotation' - | 'FloatTypeAnnotation' - | 'BooleanTypeAnnotation' - | 'GenericObjectTypeAnnotation'; - -export type PrimitiveTypeAnnotation = $ReadOnly<{| - type: PrimitiveTypeAnnotationType, -|}>; +export type NativeModuleParamTypeAnnotation = + | NativeModuleBaseTypeAnnotation + | NativeModuleParamOnlyTypeAnnotation; -export type ReservedFunctionValueTypeName = 'RootTag'; // Union with more custom types. +export type NativeModuleReturnTypeAnnotation = + | NativeModuleBaseTypeAnnotation + | NativeModuleReturnOnlyTypeAnnotation; -export type ObjectParamTypeAnnotation = $ReadOnly<{| - optional: boolean, - name: string, - typeAnnotation?: - | FunctionTypeAnnotationParamTypeAnnotation - | TypeAliasTypeAnnotation, // TODO (T67898313): Workaround for NativeLinking's use of union type, typeAnnotations should not be optional -|}>; +export type NativeModuleTypeAnnotation = + | NativeModuleBaseTypeAnnotation + | NativeModuleParamOnlyTypeAnnotation + | NativeModuleReturnOnlyTypeAnnotation; + +export type ReservedFunctionValueTypeName = 'RootTag'; // Union with more custom types. diff --git a/packages/react-native-codegen/src/parsers/flow/components/index.js b/packages/react-native-codegen/src/parsers/flow/components/index.js index eb8867401d5372..f3b9f4770fb87b 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/index.js +++ b/packages/react-native-codegen/src/parsers/flow/components/index.js @@ -167,7 +167,7 @@ function getCommandProperties(commandTypeName, types, commandOptions) { } // $FlowFixMe there's no flowtype for AST -function processComponent(ast, types): ComponentSchemaBuilderConfig { +function buildComponentSchema(ast, types): ComponentSchemaBuilderConfig { const { componentName, propsTypeName, @@ -205,5 +205,5 @@ function processComponent(ast, types): ComponentSchemaBuilderConfig { } module.exports = { - processComponent, + buildComponentSchema, }; diff --git a/packages/react-native-codegen/src/parsers/flow/components/schema.js b/packages/react-native-codegen/src/parsers/flow/components/schema.js index f55e77f162753a..c561f9e0b182fe 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/schema.js +++ b/packages/react-native-codegen/src/parsers/flow/components/schema.js @@ -29,7 +29,7 @@ export type ComponentSchemaBuilderConfig = $ReadOnly<{| options?: ?OptionsShape, |}>; -function buildComponentSchema({ +function wrapComponentSchema({ filename, componentName, extendsProps, @@ -56,5 +56,5 @@ function buildComponentSchema({ } module.exports = { - buildComponentSchema, + wrapComponentSchema, }; diff --git a/packages/react-native-codegen/src/parsers/flow/index.js b/packages/react-native-codegen/src/parsers/flow/index.js index 9e8bdb2603ae4d..6f0669f998de7e 100644 --- a/packages/react-native-codegen/src/parsers/flow/index.js +++ b/packages/react-native-codegen/src/parsers/flow/index.js @@ -15,10 +15,10 @@ import type {SchemaType} from '../../CodegenSchema.js'; const flowParser = require('flow-parser'); const fs = require('fs'); const path = require('path'); -const {buildModuleSchema} = require('./modules/schema'); -const {buildComponentSchema} = require('./components/schema'); -const {processComponent} = require('./components'); -const {processModule} = require('./modules'); +const {buildComponentSchema} = require('./components'); +const {wrapComponentSchema} = require('./components/schema'); +const {buildModuleSchema} = require('./modules'); +const {wrapModuleSchema} = require('./modules/schema'); import type {TypeDeclarationMap} from './utils'; @@ -126,13 +126,13 @@ function buildSchema(contents: string, filename: ?string): SchemaType { const configType = getConfigType(ast, types); if (configType === 'component') { - return buildComponentSchema(processComponent(ast, types)); + return wrapComponentSchema(buildComponentSchema(ast, types)); } else { if (filename === undefined || filename === null) { throw new Error('Filepath expected while parasing a module'); } const moduleName = path.basename(filename).slice(6, -3); - return buildModuleSchema(processModule(types), moduleName); + return wrapModuleSchema(buildModuleSchema(moduleName, types), moduleName); } } diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index c362d7f2ec0f8d..7a9b29a3d868c9 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -367,6 +367,7 @@ export interface Spec extends TurboModule { export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); `; + const NATIVE_MODULE_WITH_ARRAY_WITH_UNION_AND_TOUPLE = ` /** * Copyright (c) Facebook, Inc. and its affiliates. @@ -434,7 +435,7 @@ import type {TurboModule} from '../RCTExport'; import * as TurboModuleRegistry from '../TurboModuleRegistry'; export interface Spec extends TurboModule { - +getArray: (arg: Array>>>>) => Array>>; + +getArray: (arg: Array>>>>) => Array>>; } export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap index 54ae74f6566db6..96cbea8e38d1e2 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap @@ -1,16 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT 1`] = `"Unsupported return type for getString: expected to find annotation for type of array contents"`; +exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT 1`] = `"Module SampleTurboModule: Detected a type of Array, without type parameters."`; -exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT_AS_PARAM 1`] = `"Unsupported type for getString, param: \\"arg\\": expected to find annotation for type of array contents"`; +exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT_AS_PARAM 1`] = `"Module SampleTurboModule: Detected a type of Array, without type parameters."`; exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_NOT_ONLY_METHODS 1`] = `"Only methods are supported as module properties. Found BooleanTypeAnnotation in sampleBool"`; -exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_PROMISE_WITHOUT_TYPE 1`] = `"Unsupported return promise type for getBool: expected to find annotation for type of promise content"`; +exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_PROMISE_WITHOUT_TYPE 1`] = `"Module SampleTurboModule: Detected a type of Promise, without type parameters."`; -exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_READ_ONLY_OBJECT_NO_TYPE_FOR_CONTENT 1`] = `"Unsupported param for method \\"getString\\", param \\"arg\\". No type specified for $ReadOnly"`; +exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_READ_ONLY_OBJECT_NO_TYPE_FOR_CONTENT 1`] = `"Module SampleTurboModule: Detected a type of $ReadOnly, with 0 type parameters specified. Expected exactly 1."`; -exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_UNNAMED_PARAMS 1`] = `"Unsupported type for getBool. Please provide a name for every parameter."`; +exports[`RN Codegen Flow Parser Fails with error message NATIVE_MODULES_WITH_UNNAMED_PARAMS 1`] = `"Module SampleTurboModule: Detected a FunctionTypeAnnotation with an unnamed param. Please name all params."`; exports[`RN Codegen Flow Parser Fails with error message TWO_NATIVE_EXTENDING_TURBO_MODULE 1`] = `"File contains declarations of more than one module: Spec, Spec2. Please declare exactly one module in this file."`; @@ -39,11 +39,13 @@ Object { "SampleTurboModule": Object { "aliases": Object { "ObjectAlias": Object { + "nullable": false, "properties": Array [ Object { "name": "x", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -51,6 +53,7 @@ Object { "name": "y", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -58,6 +61,7 @@ Object { "name": "label", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -65,6 +69,7 @@ Object { "name": "truthy", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -81,8 +86,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -115,11 +121,13 @@ Object { "params": Array [ Object { "name": "a", - "nullable": false, + "optional": false, "typeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, }, @@ -131,6 +139,7 @@ Object { "name": "a", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -148,9 +157,10 @@ Object { "params": Array [ Object { "name": "a", - "nullable": false, + "optional": false, "typeAnnotation": Object { "name": "ObjectAlias", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -186,17 +196,20 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, }, ], "returnTypeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, "nullable": false, @@ -229,15 +242,14 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { - "elementType": undefined, + "nullable": false, "type": "ArrayTypeAnnotation", }, }, ], "returnTypeAnnotation": Object { - "elementType": undefined, "nullable": false, "type": "ArrayTypeAnnotation", }, @@ -268,17 +280,20 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, }, ], "returnTypeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, "nullable": false, @@ -295,17 +310,20 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, }, ], "returnTypeAnnotation": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, "nullable": false, @@ -338,8 +356,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -359,8 +378,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -380,8 +400,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -401,8 +422,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -438,8 +460,39 @@ Object { "params": Array [ Object { "name": "callback", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, + "params": Array [ + Object { + "name": "value", + "optional": false, + "typeAnnotation": Object { + "nullable": false, + "type": "StringTypeAnnotation", + }, + }, + Object { + "name": "arr", + "optional": false, + "typeAnnotation": Object { + "elementType": Object { + "elementType": Object { + "nullable": false, + "type": "StringTypeAnnotation", + }, + "nullable": false, + "type": "ArrayTypeAnnotation", + }, + "nullable": false, + "type": "ArrayTypeAnnotation", + }, + }, + ], + "returnTypeAnnotation": Object { + "nullable": false, + "type": "VoidTypeAnnotation", + }, "type": "FunctionTypeAnnotation", }, }, @@ -475,23 +528,29 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { "elementType": Object { "elementType": Object { "elementType": Object { "elementType": Object { "elementType": Object { - "type": "AnyTypeAnnotation", + "nullable": false, + "type": "StringTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, }, @@ -500,10 +559,13 @@ Object { "elementType": Object { "elementType": Object { "elementType": Object { + "nullable": false, "type": "StringTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, + "nullable": false, "type": "ArrayTypeAnnotation", }, "nullable": false, @@ -536,18 +598,21 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -567,11 +632,13 @@ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -593,18 +660,21 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -624,11 +694,13 @@ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -650,13 +722,15 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "a", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -680,18 +754,21 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -706,16 +783,19 @@ Object { ], "returnTypeAnnotation": Object { "elementType": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "const1", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -761,6 +841,7 @@ Object { "name": "isTesting", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -768,11 +849,13 @@ Object { "name": "reactNativeVersion", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "major", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -780,6 +863,7 @@ Object { "name": "minor", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -787,13 +871,15 @@ Object { "name": "patch", "optional": true, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, Object { "name": "prerelease", - "optional": true, + "optional": false, "typeAnnotation": Object { + "nullable": true, "type": "NumberTypeAnnotation", }, }, @@ -805,6 +891,7 @@ Object { "name": "forceTouchAvailable", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "BooleanTypeAnnotation", }, }, @@ -812,6 +899,7 @@ Object { "name": "osVersion", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -819,6 +907,7 @@ Object { "name": "systemName", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -826,6 +915,7 @@ Object { "name": "interfaceIdiom", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "StringTypeAnnotation", }, }, @@ -859,8 +949,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "Int32TypeAnnotation", }, }, @@ -880,8 +971,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "FloatTypeAnnotation", }, }, @@ -909,11 +1001,13 @@ Object { "SampleTurboModule": Object { "aliases": Object { "Bar": Object { + "nullable": false, "properties": Array [ Object { "name": "z", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -921,12 +1015,14 @@ Object { "type": "ObjectTypeAnnotation", }, "Foo": Object { + "nullable": false, "properties": Array [ Object { "name": "bar1", "optional": false, "typeAnnotation": Object { "name": "Bar", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -935,6 +1031,7 @@ Object { "optional": false, "typeAnnotation": Object { "name": "Bar", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -951,9 +1048,10 @@ Object { "params": Array [ Object { "name": "x", - "nullable": false, + "optional": false, "typeAnnotation": Object { "name": "Foo", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -974,9 +1072,10 @@ Object { "params": Array [ Object { "name": "x", - "nullable": false, + "optional": false, "typeAnnotation": Object { "name": "Foo", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -1012,8 +1111,9 @@ Object { "params": Array [ Object { "name": "arg", - "nullable": true, + "optional": false, "typeAnnotation": Object { + "nullable": true, "type": "StringTypeAnnotation", }, }, @@ -1041,11 +1141,13 @@ Object { "SampleTurboModule": Object { "aliases": Object { "DisplayMetricsAndroid": Object { + "nullable": false, "properties": Array [ Object { "name": "width", "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "NumberTypeAnnotation", }, }, @@ -1067,12 +1169,14 @@ Object { "name": "Dimensions", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "windowPhysicalPixels", "optional": false, "typeAnnotation": Object { "name": "DisplayMetricsAndroid", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -1099,12 +1203,14 @@ Object { "name": "Dimensions", "optional": false, "typeAnnotation": Object { + "nullable": false, "properties": Array [ Object { "name": "windowPhysicalPixels", "optional": false, "typeAnnotation": Object { "name": "DisplayMetricsAndroid", + "nullable": false, "type": "TypeAliasTypeAnnotation", }, }, @@ -1132,20 +1238,7 @@ Object { "NativeSampleTurboModule": Object { "nativeModules": Object { "SampleTurboModule": Object { - "aliases": Object { - "SomeObj": Object { - "properties": Array [ - Object { - "name": "a", - "optional": false, - "typeAnnotation": Object { - "type": "StringTypeAnnotation", - }, - }, - ], - "type": "ObjectTypeAnnotation", - }, - }, + "aliases": Object {}, "properties": Array [ Object { "name": "getValueWithPromise", @@ -1210,9 +1303,10 @@ Object { "params": Array [ Object { "name": "rootTag", - "nullable": false, + "optional": false, "typeAnnotation": Object { "name": "RootTag", + "nullable": false, "type": "ReservedFunctionValueTypeAnnotation", }, }, @@ -1249,8 +1343,9 @@ Object { "params": Array [ Object { "name": "o", - "nullable": false, + "optional": false, "typeAnnotation": Object { + "nullable": false, "type": "GenericObjectTypeAnnotation", }, }, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/aliases.js b/packages/react-native-codegen/src/parsers/flow/modules/aliases.js deleted file mode 100644 index b21326d8e51110..00000000000000 --- a/packages/react-native-codegen/src/parsers/flow/modules/aliases.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import type {NativeModuleAliasMap} from '../../../CodegenSchema.js'; -import type {TypeDeclarationMap} from '../utils'; - -const {getObjectProperties} = require('./properties'); - -function getAliases(types: TypeDeclarationMap): NativeModuleAliasMap { - const typeNames: Array = Object.keys(types); - return typeNames - .filter((typeName: string) => { - const declaration = types[typeName]; - return ( - declaration.type === 'TypeAlias' && - declaration.right.type === 'ObjectTypeAnnotation' - ); - }) - .reduce((aliases: NativeModuleAliasMap, aliasName: string) => { - const alias = types[aliasName]; - return { - ...aliases, - [aliasName]: { - type: 'ObjectTypeAnnotation', - properties: getObjectProperties( - aliasName, - {properties: alias.right.properties}, - aliasName, - types, - ), - }, - }; - }, ({}: NativeModuleAliasMap)); -} - -module.exports = { - getAliases, -}; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/errors.js b/packages/react-native-codegen/src/parsers/flow/modules/errors.js new file mode 100644 index 00000000000000..537e4b1aedb78f --- /dev/null +++ b/packages/react-native-codegen/src/parsers/flow/modules/errors.js @@ -0,0 +1,112 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const invariant = require('invariant'); + +class UnrecognizedFlowTypeAnnotationParserError extends Error { + +typeAnnotationType: string; + constructor(moduleName: string, typeAnnotationType: string) { + super( + `Module ${moduleName}: Detected unsupported type annotation of type '${typeAnnotationType}'`, + ); + + // assign the error class name in your custom error (as a shortcut) + this.name = this.constructor.name; + + // capturing the stack trace keeps the reference to your error class + Error.captureStackTrace(this, this.constructor); + this.typeAnnotationType = typeAnnotationType; + } +} + +class UnrecognizedFlowGenericParserError extends Error { + +genericName: string; + constructor(moduleName: string, genericName: string) { + super( + `Module ${moduleName}: Detected unsupported generic type '${genericName}'`, + ); + + // assign the error class name in your custom error (as a shortcut) + this.name = this.constructor.name; + + // capturing the stack trace keeps the reference to your error class + Error.captureStackTrace(this, this.constructor); + this.genericName = genericName; + } +} + +class FlowGenericNotTypeParameterizedParserError extends Error { + +genericName: string; + constructor(moduleName: string, genericName: string) { + super( + `Module ${moduleName}: Detected a type of ${genericName}, without type parameters.`, + ); + + // assign the error class name in your custom error (as a shortcut) + this.name = this.constructor.name; + + // capturing the stack trace keeps the reference to your error class + Error.captureStackTrace(this, this.constructor); + this.genericName = genericName; + } +} + +class FlowGenericTypeParameterCountMismatchParserError extends Error { + +genericName: string; + +numTypeParameters: number; + + constructor( + moduleName: string, + genericName: string, + numTypeParameters: number, + expectedNumTypeParameters: number, + ) { + invariant( + numTypeParameters !== expectedNumTypeParameters, + `FlowGenericNotTypeParameterizedWithExactlyOneTypeParserError can only be created with numTypeParameters != ${expectedNumTypeParameters}`, + ); + + super( + `Module ${moduleName}: Detected a type of ${genericName}, with ${numTypeParameters} type parameters specified. Expected exactly ${expectedNumTypeParameters}.`, + ); + + // assign the error class name in your custom error (as a shortcut) + this.name = this.constructor.name; + + // capturing the stack trace keeps the reference to your error class + Error.captureStackTrace(this, this.constructor); + this.genericName = genericName; + this.numTypeParameters = numTypeParameters; + } +} + +class UnnamedFunctionTypeAnnotationParamError extends Error { + constructor(moduleName: string) { + super( + `Module ${moduleName}: Detected a FunctionTypeAnnotation with an unnamed param. Please name all params.`, + ); + + // assign the error class name in your custom error (as a shortcut) + this.name = this.constructor.name; + + // capturing the stack trace keeps the reference to your error class + Error.captureStackTrace(this, this.constructor); + } +} + +module.exports = { + FlowGenericNotTypeParameterizedParserError, + FlowGenericTypeParameterCountMismatchParserError, + UnrecognizedFlowTypeAnnotationParserError, + UnrecognizedFlowGenericParserError, + UnnamedFunctionTypeAnnotationParamError, +}; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 1b52cb7da220d2..98dc32c5abdba1 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -10,18 +10,415 @@ 'use strict'; -import type {NativeModuleShape} from '../../../CodegenSchema'; -const {getAliases} = require('./aliases'); -const {getMethods} = require('./methods'); +import type { + NativeModulePropertySchema, + NativeModuleMethodParamSchema, + NativeModuleAliasMap, + NativeModuleSchema, + NativeModuleFunctionTypeAnnotation, +} from '../../../CodegenSchema.js'; -import type {TypeDeclarationMap} from '../utils'; +import type {TypeDeclarationMap} from '../utils.js'; +const {resolveTypeAnnotation} = require('../utils.js'); +const { + FlowGenericNotTypeParameterizedParserError, + FlowGenericTypeParameterCountMismatchParserError, + UnrecognizedFlowTypeAnnotationParserError, + UnrecognizedFlowGenericParserError, + UnnamedFunctionTypeAnnotationParamError, +} = require('./errors.js'); +const invariant = require('invariant'); -function processModule(types: TypeDeclarationMap): NativeModuleShape { - const properties = getMethods(types); - const aliases = getAliases(types); - return {aliases, properties}; +import type {NativeModuleTypeAnnotation} from '../../../CodegenSchema.js'; + +function translateTypeAnnotation( + moduleName: string, + /** + * TODO(T71778680): Flow-type this node. + */ + flowTypeAnnotation: $FlowFixMe, + types: TypeDeclarationMap, + aliasMap: NativeModuleAliasMap, +): NativeModuleTypeAnnotation { + const {nullable, typeAnnotation} = resolveTypeAnnotation( + flowTypeAnnotation, + types, + ); + + switch (typeAnnotation.type) { + case 'GenericTypeAnnotation': { + switch (typeAnnotation.id.name) { + case 'RootTag': + return { + nullable, + type: 'ReservedFunctionValueTypeAnnotation', + name: 'RootTag', + }; + case 'Promise': { + assertGenericTypeAnnotationHasExactlyOneTypeParameter( + moduleName, + typeAnnotation, + ); + return { + nullable, + type: 'GenericPromiseTypeAnnotation', + }; + } + case 'Array': + case '$ReadOnlyArray': { + assertGenericTypeAnnotationHasExactlyOneTypeParameter( + moduleName, + typeAnnotation, + ); + + try { + /** + * TODO(T72031674): Migrate all our NativeModule specs to not use + * invalid Array ElementTypes. Then, make the elementType a required + * parameter. + */ + const elementType = translateTypeAnnotation( + moduleName, + typeAnnotation.typeParameters.params[0], + types, + aliasMap, + ); + + invariant( + elementType.type !== 'VoidTypeAnnotation', + `${typeAnnotation.id.name} element type cannot be 'void'.`, + ); + invariant( + elementType.type !== 'GenericPromiseTypeAnnotation', + `${typeAnnotation.id.name} element type cannot be 'Promise'.`, + ); + + invariant( + elementType.type !== 'FunctionTypeAnnotation', + `${typeAnnotation.id.name} element type cannot be a function.`, + ); + + return { + nullable, + type: 'ArrayTypeAnnotation', + elementType: elementType, + }; + } catch (ex) { + return { + nullable, + type: 'ArrayTypeAnnotation', + }; + } + } + case '$ReadOnly': { + assertGenericTypeAnnotationHasExactlyOneTypeParameter( + moduleName, + typeAnnotation, + ); + return translateTypeAnnotation( + moduleName, + typeAnnotation.typeParameters.params[0], + types, + aliasMap, + ); + } + case 'Stringish': { + return { + nullable, + type: 'StringTypeAnnotation', + }; + } + case 'Int32': { + return { + nullable, + type: 'Int32TypeAnnotation', + }; + } + case 'Double': { + return { + nullable, + type: 'DoubleTypeAnnotation', + }; + } + case 'Float': { + return { + nullable, + type: 'FloatTypeAnnotation', + }; + } + case 'Object': { + return { + nullable, + type: 'GenericObjectTypeAnnotation', + }; + } + default: { + throw new UnrecognizedFlowGenericParserError( + moduleName, + typeAnnotation.id.name, + ); + } + } + } + case 'ObjectTypeAnnotation': { + const objectTypeAnnotation = { + nullable, + type: 'ObjectTypeAnnotation', + properties: typeAnnotation.properties.map(property => { + const {optional} = property; + return { + name: property.key.name, + optional, + typeAnnotation: translateTypeAnnotation( + moduleName, + property.value, + types, + aliasMap, + ), + }; + }), + }; + + if (flowTypeAnnotation.type === 'GenericTypeAnnotation') { + aliasMap[flowTypeAnnotation.id.name] = objectTypeAnnotation; + return { + nullable: false, + type: 'TypeAliasTypeAnnotation', + name: flowTypeAnnotation.id.name, + }; + } + + if ( + flowTypeAnnotation.type === 'NullableTypeAnnotation' && + flowTypeAnnotation.typeAnnotation.type === 'GenericTypeAnnotation' + ) { + aliasMap[ + flowTypeAnnotation.typeAnnotation.id.name + ] = objectTypeAnnotation; + return { + nullable: true, + type: 'TypeAliasTypeAnnotation', + name: flowTypeAnnotation.typeAnnotation.id.name, + }; + } + + return objectTypeAnnotation; + } + case 'BooleanTypeAnnotation': { + return { + nullable, + type: 'BooleanTypeAnnotation', + }; + } + case 'NumberTypeAnnotation': { + return { + nullable, + type: 'NumberTypeAnnotation', + }; + } + case 'VoidTypeAnnotation': { + return { + nullable, + type: 'VoidTypeAnnotation', + }; + } + case 'StringTypeAnnotation': { + return { + nullable, + type: 'StringTypeAnnotation', + }; + } + case 'FunctionTypeAnnotation': { + return translateFunctionTypeAnnotation( + moduleName, + typeAnnotation, + types, + nullable, + aliasMap, + ); + } + default: { + throw new UnrecognizedFlowTypeAnnotationParserError( + moduleName, + typeAnnotation.type, + ); + } + } +} + +function assertGenericTypeAnnotationHasExactlyOneTypeParameter( + moduleName: string, + /** + * TODO(T71778680): This is a GenericTypeAnnotation. Flow type this node + */ + typeAnnotation: $FlowFixMe, +) { + if (typeAnnotation.typeParameters == null) { + throw new FlowGenericNotTypeParameterizedParserError( + moduleName, + typeAnnotation.id.name, + ); + } + + invariant( + typeAnnotation.typeParameters.type === 'TypeParameterInstantiation', + "assertGenericTypeAnnotationHasExactlyOneTypeParameter: Type parameters must be an AST node of type 'TypeParameterInstantiation'", + ); + + if (typeAnnotation.typeParameters.params.length !== 1) { + throw new FlowGenericTypeParameterCountMismatchParserError( + moduleName, + typeAnnotation.id.name, + (typeAnnotation.typeParameters.params.length: number), + 1, + ); + } +} + +function translateFunctionTypeAnnotation( + moduleName: string, + // TODO(T71778680): This is a FunctionTypeAnnotation. Type this. + flowFunctionTypeAnnotation: $FlowFixMe, + types: TypeDeclarationMap, + nullable: boolean, + aliasMap: NativeModuleAliasMap, +): NativeModuleFunctionTypeAnnotation { + const params: Array = []; + for (const flowParam of (flowFunctionTypeAnnotation.params: $ReadOnlyArray<$FlowFixMe>)) { + if (flowParam.name == null) { + throw new UnnamedFunctionTypeAnnotationParamError(moduleName); + } + + const paramName = flowParam.name.name; + const paramTypeAnnotation = translateTypeAnnotation( + moduleName, + flowParam.typeAnnotation, + types, + aliasMap, + ); + + invariant( + paramTypeAnnotation.type !== 'VoidTypeAnnotation', + `Parameter ${paramName} cannot have type 'void'.`, + ); + + invariant( + paramTypeAnnotation.type !== 'GenericPromiseTypeAnnotation', + `Parameter ${paramName} cannot have type 'Promise'.`, + ); + + params.push({ + name: flowParam.name.name, + optional: flowParam.optional, + typeAnnotation: paramTypeAnnotation, + }); + } + + const returnTypeAnnotation = translateTypeAnnotation( + moduleName, + flowFunctionTypeAnnotation.returnType, + types, + aliasMap, + ); + + invariant( + returnTypeAnnotation.type !== 'FunctionTypeAnnotation', + "Return cannot have type 'Promise'.", + ); + + return { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation, + params, + nullable, + }; +} + +function buildPropertySchema( + moduleName: string, + // TODO(T71778680): This is an ObjectTypeProperty containing either: + // - a FunctionTypeAnnotation or GenericTypeAnnotation + // - a NullableTypeAnnoation containing a FunctionTypeAnnotation or GenericTypeAnnotation + // Flow type this node + property: $FlowFixMe, + types: TypeDeclarationMap, + aliasMap: NativeModuleAliasMap, +): NativeModulePropertySchema { + let nullable = false; + let {key, value} = property; + + const methodName: string = key.name; + + ({nullable, typeAnnotation: value} = resolveTypeAnnotation(value, types)); + + if (value.type !== 'FunctionTypeAnnotation') { + throw new Error( + `Only methods are supported as module properties. Found ${value.type} in ${property.key.name}`, + ); + } + + return { + name: methodName, + optional: property.optional, + typeAnnotation: translateFunctionTypeAnnotation( + moduleName, + value, + types, + nullable, + aliasMap, + ), + }; +} + +function buildModuleSchema( + moduleName: string, + types: TypeDeclarationMap, +): NativeModuleSchema { + const moduleInterfaceNames = (Object.keys( + types, + ): $ReadOnlyArray).filter((typeName: string) => { + const declaration = types[typeName]; + return ( + declaration.type === 'InterfaceDeclaration' && + declaration.extends.length === 1 && + declaration.extends[0].type === 'InterfaceExtends' && + declaration.extends[0].id.name === 'TurboModule' + ); + }); + + invariant( + moduleInterfaceNames.length === 1, + 'There must be exactly one module declaration per file.', + ); + + const [moduleInterfaceName] = moduleInterfaceNames; + + const declaration = types[moduleInterfaceName]; + return (declaration.body.properties: $ReadOnlyArray<$FlowFixMe>) + .filter(property => property.type === 'ObjectTypeProperty') + .map(property => { + const aliasMap: NativeModuleAliasMap = {}; + return { + aliasMap: aliasMap, + propertySchema: buildPropertySchema( + moduleName, + property, + types, + aliasMap, + ), + }; + }) + .reduce( + (moduleSchema: NativeModuleSchema, {aliasMap, propertySchema}) => { + return { + aliases: {...moduleSchema.aliases, ...aliasMap}, + properties: [...moduleSchema.properties, propertySchema], + }; + }, + {aliases: {}, properties: []}, + ); } module.exports = { - processModule, + buildModuleSchema, }; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/methods.js b/packages/react-native-codegen/src/parsers/flow/modules/methods.js deleted file mode 100644 index e3773c01215874..00000000000000 --- a/packages/react-native-codegen/src/parsers/flow/modules/methods.js +++ /dev/null @@ -1,394 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import type { - NativeModulePropertyShape, - FunctionTypeAnnotationParam, - FunctionTypeAnnotationReturn, -} from '../../../CodegenSchema.js'; - -import type {ASTNode, TypeDeclarationMap} from '../utils.js'; -const {getValueFromTypes} = require('../utils.js'); -const { - getElementTypeForArrayOrObject, - getObjectProperties, -} = require('./properties'); -const invariant = require('invariant'); - -function getTypeAnnotationForParam( - name: string, - paramAnnotation: ASTNode, - types: TypeDeclarationMap, -): FunctionTypeAnnotationParam { - let param = paramAnnotation; - if (param.name === null) { - throw new Error( - `Unsupported type for ${name}. Please provide a name for every parameter.`, - ); - } - let paramName = param.name.name; - let nullable = false; - if (param.typeAnnotation.type === 'NullableTypeAnnotation') { - nullable = true; - param = paramAnnotation.typeAnnotation; - } - - const typeAnnotation = getValueFromTypes(param.typeAnnotation, types); - const type = - typeAnnotation.type === 'GenericTypeAnnotation' - ? typeAnnotation.id.name - : typeAnnotation.type; - - switch (type) { - case 'RootTag': - return { - name: paramName, - nullable, - typeAnnotation: { - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }, - }; - case 'Array': - case '$ReadOnlyArray': - if ( - typeAnnotation.typeParameters && - typeAnnotation.typeParameters.params[0] - ) { - return { - name: paramName, - nullable, - typeAnnotation: { - type: 'ArrayTypeAnnotation', - elementType: getElementTypeForArrayOrObject( - name, - typeAnnotation.typeParameters.params[0], - paramName, - types, - ), - }, - }; - } else { - throw new Error( - `Unsupported type for ${name}, param: "${paramName}": expected to find annotation for type of array contents`, - ); - } - case 'ObjectTypeAnnotation': - if (param.typeAnnotation.type === 'GenericTypeAnnotation') { - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'TypeAliasTypeAnnotation', - name: param.typeAnnotation.id.name, - }, - }; - } - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: getObjectProperties( - name, - typeAnnotation, - paramName, - types, - ), - }, - }; - case '$ReadOnly': - if ( - typeAnnotation.typeParameters.params && - typeAnnotation.typeParameters.params[0] - ) { - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: getObjectProperties( - name, - typeAnnotation.typeParameters.params[0], - paramName, - types, - ), - }, - }; - } else { - throw new Error( - `Unsupported param for method "${name}", param "${paramName}". No type specified for $ReadOnly`, - ); - } - case 'FunctionTypeAnnotation': - return { - name: paramName, - nullable, - typeAnnotation: { - type: 'FunctionTypeAnnotation', - }, - }; - case 'NumberTypeAnnotation': - case 'BooleanTypeAnnotation': - return { - nullable, - name: paramName, - typeAnnotation: { - type, - }, - }; - - case 'StringTypeAnnotation': - case 'Stringish': - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }; - case 'Int32': - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'Int32TypeAnnotation', - }, - }; - case 'Float': - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'FloatTypeAnnotation', - }, - }; - default: - return { - nullable, - name: paramName, - typeAnnotation: { - type: 'GenericObjectTypeAnnotation', - }, - }; - } -} - -function getReturnTypeAnnotation( - methodName: string, - returnType, - types: TypeDeclarationMap, -): FunctionTypeAnnotationReturn { - let typeAnnotation = getValueFromTypes(returnType, types); - let nullable = false; - if (typeAnnotation.type === 'NullableTypeAnnotation') { - nullable = true; - typeAnnotation = typeAnnotation.typeAnnotation; - } - let type = - typeAnnotation.type === 'GenericTypeAnnotation' - ? typeAnnotation.id.name - : typeAnnotation.type; - - switch (type) { - case 'RootTag': - return { - nullable, - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }; - case 'Promise': - if ( - typeAnnotation.typeParameters && - typeAnnotation.typeParameters.params[0] - ) { - return { - type: 'GenericPromiseTypeAnnotation', - nullable, - }; - } else { - throw new Error( - `Unsupported return promise type for ${methodName}: expected to find annotation for type of promise content`, - ); - } - case 'Array': - case '$ReadOnlyArray': - if ( - typeAnnotation.typeParameters && - typeAnnotation.typeParameters.params[0] - ) { - return { - nullable, - type: 'ArrayTypeAnnotation', - elementType: getElementTypeForArrayOrObject( - methodName, - typeAnnotation.typeParameters.params[0], - 'returning value', - types, - ), - }; - } else { - throw new Error( - `Unsupported return type for ${methodName}: expected to find annotation for type of array contents`, - ); - } - case 'ObjectTypeAnnotation': - if (returnType.type === 'GenericTypeAnnotation') { - return { - nullable, - type: 'TypeAliasTypeAnnotation', - name: returnType.id.name, - }; - } - return { - nullable, - type: 'ObjectTypeAnnotation', - properties: getObjectProperties( - methodName, - typeAnnotation, - 'returning value', - types, - ), - }; - case '$ReadOnly': - if ( - typeAnnotation.typeParameters.params && - typeAnnotation.typeParameters.params[0] - ) { - return { - nullable, - type: 'ObjectTypeAnnotation', - properties: getObjectProperties( - methodName, - typeAnnotation.typeParameters.params[0], - 'returning value', - types, - ), - }; - } else { - throw new Error( - `Unsupported return type for method "${methodName}", No type specified for $ReadOnly`, - ); - } - case 'BooleanTypeAnnotation': - case 'NumberTypeAnnotation': - case 'VoidTypeAnnotation': - return { - nullable, - type, - }; - case 'StringTypeAnnotation': - case 'Stringish': - return { - nullable, - type: 'StringTypeAnnotation', - }; - - case 'Int32': - return { - nullable, - type: 'Int32TypeAnnotation', - }; - case 'Float': - return { - nullable, - type: 'FloatTypeAnnotation', - }; - default: - return { - type: 'GenericObjectTypeAnnotation', - nullable, - }; - } -} - -function buildMethodSchema( - // TODO(T71778680): This is an ObjectTypeProperty containing either: - // - a FunctionTypeAnnotation or GenericTypeAnnotation - // - a NullableTypeAnnoation containing a FunctionTypeAnnotation or GenericTypeAnnotation - // Flow type this node - property: $FlowFixMe, - types: TypeDeclarationMap, -): NativeModulePropertyShape { - let nullable = false; - let {key, value} = property; - - // Unwrap Nullable types - if (value.type === 'NullableTypeAnnotation') { - nullable = true; - value = value.typeAnnotation; - } - - const name: string = key.name; - - // Resolve type aliases - if (value.type === 'GenericTypeAnnotation') { - value = getValueFromTypes(value, types); - } - - if (value.type !== 'FunctionTypeAnnotation') { - throw new Error( - `Only methods are supported as module properties. Found ${value.type} in ${property.key.name}`, - ); - } - - const params = value.params.map(param => - getTypeAnnotationForParam(name, param, types), - ); - - const returnTypeAnnotation = getReturnTypeAnnotation( - name, - value.returnType, - types, - ); - - return { - name, - optional: property.optional, - typeAnnotation: { - type: 'FunctionTypeAnnotation', - returnTypeAnnotation, - params, - nullable, - }, - }; -} - -function getMethods( - types: TypeDeclarationMap, -): $ReadOnlyArray { - const moduleInterfaceNames = Object.keys(types).filter((typeName: string) => { - const declaration = types[typeName]; - return ( - declaration.type === 'InterfaceDeclaration' && - declaration.extends.length === 1 && - declaration.extends[0].type === 'InterfaceExtends' && - declaration.extends[0].id.name === 'TurboModule' - ); - }); - - invariant( - moduleInterfaceNames.length === 1, - 'There must be exactly one module declaration per file', - ); - - const [moduleInterfaceName] = moduleInterfaceNames; - - const declaration = types[moduleInterfaceName]; - return declaration.body.properties - .filter(property => property.type === 'ObjectTypeProperty') - .map(property => buildMethodSchema(property, types)); -} - -module.exports = { - getMethods, -}; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/properties.js b/packages/react-native-codegen/src/parsers/flow/modules/properties.js deleted file mode 100644 index b1c1bbb11ed16c..00000000000000 --- a/packages/react-native-codegen/src/parsers/flow/modules/properties.js +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import type { - FunctionTypeAnnotationParamTypeAnnotation, - ObjectParamTypeAnnotation, - TypeAliasTypeAnnotation, -} from '../../../CodegenSchema.js'; - -import type {ASTNode, TypeDeclarationMap} from '../utils.js'; -const {getValueFromTypes} = require('../utils.js'); - -function getObjectProperties( - name: string, - objectParam: ASTNode, - paramName: string, - types: TypeDeclarationMap, -): $ReadOnlyArray { - return objectParam.properties.map(objectTypeProperty => { - let optional = objectTypeProperty.optional; - let value = objectTypeProperty.value; - if (value.type === 'NullableTypeAnnotation') { - if ( - objectTypeProperty.value.typeAnnotation.type !== 'StringTypeAnnotation' - ) { - optional = true; - } - value = objectTypeProperty.value.typeAnnotation; - } - return { - optional, - name: objectTypeProperty.key.name, - typeAnnotation: getElementTypeForArrayOrObject( - name, - value, - paramName, - types, - ), - }; - }); -} - -function getElementTypeForArrayOrObject( - name: string, - arrayParam: ASTNode, - paramName: string, - types: TypeDeclarationMap, -): - | FunctionTypeAnnotationParamTypeAnnotation - | TypeAliasTypeAnnotation - | typeof undefined { - const typeAnnotation = getValueFromTypes(arrayParam, types); - const type = - typeAnnotation.type === 'GenericTypeAnnotation' - ? typeAnnotation.id.name - : typeAnnotation.type; - - switch (type) { - case 'RootTag': - return { - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }; - case 'Array': - case '$ReadOnlyArray': - if ( - typeAnnotation.typeParameters && - typeAnnotation.typeParameters.params[0] - ) { - return { - type: 'ArrayTypeAnnotation', - elementType: getElementTypeForArrayOrObject( - name, - typeAnnotation.typeParameters.params[0], - 'returning value', - types, - ), - }; - } else { - throw new Error( - `Unsupported type for "${name}", param: "${paramName}": expected to find annotation for type of nested array contents`, - ); - } - case 'ObjectTypeAnnotation': - if (arrayParam.id) { - return { - type: 'TypeAliasTypeAnnotation', - name: arrayParam.id.name, - }; - } - return { - type: 'ObjectTypeAnnotation', - properties: getObjectProperties(name, typeAnnotation, paramName, types), - }; - case '$ReadOnly': - if ( - typeAnnotation.typeParameters.params && - typeAnnotation.typeParameters.params[0] - ) { - return { - type: 'ObjectTypeAnnotation', - properties: getObjectProperties( - name, - typeAnnotation.typeParameters.params[0], - paramName, - types, - ), - }; - } else { - throw new Error( - `Unsupported param for method "${name}", param "${paramName}". No type specified for $ReadOnly`, - ); - } - case 'AnyTypeAnnotation': - return { - type, - }; - case 'NumberTypeAnnotation': - case 'BooleanTypeAnnotation': - return { - type, - }; - case 'StringTypeAnnotation': - case 'Stringish': - return { - type: 'StringTypeAnnotation', - }; - case 'Int32': - return { - type: 'Int32TypeAnnotation', - }; - case 'Float': - return { - type: 'FloatTypeAnnotation', - }; - case 'TupleTypeAnnotation': - case 'UnionTypeAnnotation': - return undefined; - default: - // TODO T67565166: Generic objects are not type safe and should be disallowed in the schema. - return { - type: 'GenericObjectTypeAnnotation', - }; - } -} - -module.exports = { - getElementTypeForArrayOrObject, - getObjectProperties, -}; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/schema.js b/packages/react-native-codegen/src/parsers/flow/modules/schema.js index 34e6b1531050b3..f54053a0c86d84 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/schema.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/schema.js @@ -10,10 +10,10 @@ 'use strict'; -import type {SchemaType, NativeModuleShape} from '../../../CodegenSchema.js'; +import type {SchemaType, NativeModuleSchema} from '../../../CodegenSchema.js'; -function buildModuleSchema( - {aliases, properties}: NativeModuleShape, +function wrapModuleSchema( + {aliases, properties}: NativeModuleSchema, moduleName: string, ): SchemaType { return { @@ -31,5 +31,5 @@ function buildModuleSchema( } module.exports = { - buildModuleSchema, + wrapModuleSchema, }; diff --git a/packages/react-native-codegen/src/parsers/flow/utils.js b/packages/react-native-codegen/src/parsers/flow/utils.js index 7e1e57f2989c7f..87ec1894c068db 100644 --- a/packages/react-native-codegen/src/parsers/flow/utils.js +++ b/packages/react-native-codegen/src/parsers/flow/utils.js @@ -23,6 +23,47 @@ export type TypeDeclarationMap = {|[declarationName: string]: $FlowFixMe|}; // $FlowFixMe there's no flowtype for ASTs export type ASTNode = Object; +const invariant = require('invariant'); + +function resolveTypeAnnotation( + // TODO(T71778680): This is an Flow TypeAnnotation. Flow-type this + typeAnnotation: $FlowFixMe, + types: TypeDeclarationMap, +): {nullable: boolean, typeAnnotation: $FlowFixMe} { + invariant( + typeAnnotation != null, + 'resolveTypeAnnotation(): typeAnnotation cannot be null', + ); + + let node = typeAnnotation; + let nullable = false; + + for (;;) { + if (node.type === 'NullableTypeAnnotation') { + nullable = true; + node = node.typeAnnotation; + } else if (node.type === 'GenericTypeAnnotation') { + const resolvedTypeAnnotation = types[node.id.name]; + if (resolvedTypeAnnotation == null) { + break; + } + + invariant( + resolvedTypeAnnotation.type === 'TypeAlias', + `GenericTypeAnnotation '${node.id.name}' must resolve to a TypeAlias. Instead, it resolved to a '${resolvedTypeAnnotation.type}'`, + ); + node = resolvedTypeAnnotation.right; + } else { + break; + } + } + + return { + nullable: nullable, + typeAnnotation: node, + }; +} + function getValueFromTypes(value: ASTNode, types: TypeDeclarationMap): ASTNode { if (value.type === 'GenericTypeAnnotation' && types[value.id.name]) { return getValueFromTypes(types[value.id.name].right, types); @@ -32,4 +73,5 @@ function getValueFromTypes(value: ASTNode, types: TypeDeclarationMap): ASTNode { module.exports = { getValueFromTypes, + resolveTypeAnnotation, }; From aba4e878734b073230244d331a8a83b2fb8c8bf4 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 16/52] Add unit tests to validate module parser Summary: ## Test Structure - Parameter Parsing - For type in [optional, nullable, optional and nullable, required]: - Can parse Primitives - Can parse Object - Can parse Arrays - Can parse primitive element types - Can parse Object element types - Can parse Array element types - Can parse Reserved Type element types - Can parse Type alias element types - Can parse Object Literals - Can parse Function - Can parse Reserved Types (e.g: RootTag) - Can parse Type alias - Can parse Object Literals - For prop type in [optional, nullable, optional and nullable, required]: - Can parse primitive prop types - Can parse Object prop types - Can parse Array prop types - Can parse Reserved Type prop types - Can parse Type alias prop types - Can parse Object Literal prop types - Return Parsing - For type in [nullable, required]: - Can parse Promises - Can parse Primitives - Can parse Object - Can parse Arrays - Can parse primitive element types - Can parse Object element types - Can parse Array element types - Can parse Reserved Type element types - Can parse Type alias element types - Can parse Object Literals - Can parse Function - Can parse Reserved Types (e.g: RootTag) - Can parse Type aliases - Can parse Object Literals - For prop type in [optional, nullable, optional and nullable, required]: - Can parse primitive prop types - Can parse Object prop types - Can parse Array prop types - Can parse Reserved Type prop types - Can parse Type alias prop types - Can parse Object Literal prop types Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23089925 fbshipit-source-id: 73c3b1ef33b402265c14f0ac9e364414a5d54dca --- ...ap => module-parser-snapshot-test.js.snap} | 0 .../__tests__/module-parser-e2e-test.js | 1083 +++++++++++++++++ ...test.js => module-parser-snapshot-test.js} | 0 3 files changed, 1083 insertions(+) rename packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/{module-parser-test.js.snap => module-parser-snapshot-test.js.snap} (100%) create mode 100644 packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js rename packages/react-native-codegen/src/parsers/flow/modules/__tests__/{module-parser-test.js => module-parser-snapshot-test.js} (100%) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap similarity index 100% rename from packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap rename to packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js new file mode 100644 index 00000000000000..734e456922f510 --- /dev/null +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js @@ -0,0 +1,1083 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import type {ReservedFunctionValueTypeName} from '../../../../CodegenSchema'; +const {parseString} = require('../../index.js'); +const { + FlowGenericNotTypeParameterizedParserError, + UnrecognizedFlowTypeAnnotationParserError, + UnrecognizedFlowGenericParserError, + UnnamedFunctionTypeAnnotationParamError, +} = require('../errors.js'); +const invariant = require('invariant'); + +type PrimitiveTypeAnnotationType = + | 'StringTypeAnnotation' + | 'NumberTypeAnnotation' + | 'Int32TypeAnnotation' + | 'DoubleTypeAnnotation' + | 'FloatTypeAnnotation' + | 'BooleanTypeAnnotation'; + +const PRIMITIVES: $ReadOnlyArray<[string, PrimitiveTypeAnnotationType]> = [ + ['string', 'StringTypeAnnotation'], + ['number', 'NumberTypeAnnotation'], + ['Int32', 'Int32TypeAnnotation'], + ['Double', 'DoubleTypeAnnotation'], + ['Float', 'FloatTypeAnnotation'], + ['boolean', 'BooleanTypeAnnotation'], +]; + +const RESERVED_FUNCTION_VALUE_TYPE_NAME: $ReadOnlyArray = [ + 'RootTag', +]; + +const MODULE_NAME = 'Foo'; + +describe('Flow Module Parser', () => { + describe('Parameter Parsing', () => { + it("should fail parsing when a method has an parameter of type 'any'", () => { + const parser = () => + parseModule(` + import type {TurboModule} from 'RCTExport'; + import * as TurboModuleRegistry from 'TurboModuleRegistry'; + export interface Spec extends TurboModule { + +useArg(arg: any): void; + } + export default TurboModuleRegistry.get('Foo'); + `); + + expect(parser).toThrow( + new UnrecognizedFlowTypeAnnotationParserError( + MODULE_NAME, + 'AnyTypeAnnotation', + ), + ); + }); + + it('should fail parsing when a function param type is unamed', () => { + const parser = () => + parseModule(` + import type {TurboModule} from 'RCTExport'; + import * as TurboModuleRegistry from 'TurboModuleRegistry'; + export interface Spec extends TurboModule { + +useArg(boolean): void; + } + export default TurboModuleRegistry.get('Foo'); + `); + + expect(parser).toThrow( + new UnnamedFunctionTypeAnnotationParamError(MODULE_NAME), + ); + }); + + [ + {nullable: false, optional: false}, + {nullable: false, optional: true}, + {nullable: true, optional: false}, + {nullable: true, optional: true}, + ].forEach(({nullable, optional}) => { + const PARAM_TYPE_DESCRIPTION = + nullable && optional + ? 'a nullable and optional' + : nullable + ? 'a nullable' + : optional + ? 'an optional' + : 'a required'; + + function annotateArg(paramName: string, paramType: string) { + if (nullable && optional) { + return `${paramName}?: ?${paramType}`; + } + if (nullable) { + return `${paramName}: ?${paramType}`; + } + if (optional) { + return `${paramName}?: ${paramType}`; + } + return `${paramName}: ${paramType}`; + } + + function parseParamType(paramName: string, paramType: string) { + const module = parseModule(` + import type {TurboModule} from 'RCTExport'; + import * as TurboModuleRegistry from 'TurboModuleRegistry'; + + type Animal = {| + name: string, + |}; + + export interface Spec extends TurboModule { + +useArg(${annotateArg(paramName, paramType)}): void; + } + export default TurboModuleRegistry.get('Foo'); + `); + + expect(module.properties[0]).not.toBe(null); + const param = module.properties[0].typeAnnotation.params[0]; + expect(param).not.toBe(null); + expect(param.name).toBe(paramName); + expect(param.optional).toBe(optional); + expect(param.typeAnnotation.nullable).toBe(nullable); + + return param; + } + + describe( + (nullable && optional + ? 'Nullable and Optional' + : nullable + ? 'Nullable' + : optional + ? 'Optional' + : 'Required') + ' Parameter', + () => { + it(`should not parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Function'`, () => { + expect(() => parseParamType('arg', 'Function')).toThrow( + new UnrecognizedFlowGenericParserError(MODULE_NAME, 'Function'), + ); + }); + + describe('Primitive types', () => { + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} primitive parameter of type '${FLOW_TYPE}'`, () => { + const param = parseParamType('arg', FLOW_TYPE); + expect(param.typeAnnotation.type).toBe(PARSED_TYPE_NAME); + }); + }); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Object'`, () => { + const param = parseParamType('arg', 'Object'); + expect(param.typeAnnotation.type).toBe( + 'GenericObjectTypeAnnotation', + ); + }); + + describe('Reserved Types', () => { + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of reserved type '${FLOW_TYPE}'`, () => { + const param = parseParamType('arg', FLOW_TYPE); + + expect(param.typeAnnotation.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + param.typeAnnotation.type === + 'ReservedFunctionValueTypeAnnotation', + 'Param must be a Reserved type', + ); + + expect(param.typeAnnotation.name).toBe(FLOW_TYPE); + }); + }); + }); + + describe('Array Types', () => { + it(`should not parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array'`, () => { + expect(() => parseParamType('arg', 'Array')).toThrow( + new FlowGenericNotTypeParameterizedParserError( + MODULE_NAME, + 'Array', + ), + ); + }); + + function parseParamArrayElementType( + paramName: string, + paramType: string, + ) { + const param = parseParamType(paramName, `Array<${paramType}>`); + + expect(param.typeAnnotation.type).toBe('ArrayTypeAnnotation'); + invariant( + param.typeAnnotation.type === 'ArrayTypeAnnotation', + '', + ); + + expect(param.typeAnnotation.elementType).not.toBe(null); + invariant(param.typeAnnotation.elementType != null, ''); + return param.typeAnnotation.elementType; + } + + // TODO: Do we support nullable element types? + + describe('Primitive Element Types', () => { + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseParamArrayElementType( + 'arg', + FLOW_TYPE, + ); + expect(elementType.type).toBe(PARSED_TYPE_NAME); + }); + }); + }); + + describe('Reserved Element Types', () => { + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseParamArrayElementType( + 'arg', + FLOW_TYPE, + ); + expect(elementType.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + elementType.type === 'ReservedFunctionValueTypeAnnotation', + '', + ); + + expect(elementType.name).toBe(FLOW_TYPE); + }); + }); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array'`, () => { + const elementType = parseParamArrayElementType('arg', 'Object'); + expect(elementType.type).toBe('GenericObjectTypeAnnotation'); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of some array of an alias`, () => { + const elementType = parseParamArrayElementType('arg', 'Animal'); + expect(elementType.type).toBe('TypeAliasTypeAnnotation'); + invariant(elementType.type === 'TypeAliasTypeAnnotation', ''); + + expect(elementType.name).toBe('Animal'); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array<{|foo: ?string|}>'`, () => { + const elementType = parseParamArrayElementType( + 'arg', + '{|foo: ?string|}', + ); + expect(elementType).not.toBe(null); + + expect(elementType.type).toBe('ObjectTypeAnnotation'); + invariant(elementType.type === 'ObjectTypeAnnotation', ''); + + const {properties} = elementType; + invariant(properties != null, ''); + + expect(properties).not.toBe(null); + expect(properties[0]).not.toBe(null); + expect(properties[0].name).toBe('foo'); + expect(properties[0].typeAnnotation).not.toBe(null); + expect(properties[0].typeAnnotation?.type).toBe( + 'StringTypeAnnotation', + ); + expect(properties[0].typeAnnotation?.nullable).toBe(true); + expect(properties[0].optional).toBe(false); + }); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of some type alias`, () => { + const param = parseParamType('arg', 'Animal'); + expect(param.typeAnnotation.type).toBe('TypeAliasTypeAnnotation'); + invariant( + param.typeAnnotation.type === 'TypeAliasTypeAnnotation', + '', + ); + + expect(param.typeAnnotation.name).toBe('Animal'); + }); + + [ + {nullable: false, optional: false}, + {nullable: false, optional: true}, + {nullable: true, optional: false}, + {nullable: true, optional: true}, + ].forEach(({nullable: isPropNullable, optional: isPropOptional}) => { + const PROP_TYPE_DESCRIPTION = + isPropNullable && isPropOptional + ? 'a nullable and optional' + : isPropNullable + ? 'a nullable' + : isPropOptional + ? 'an optional' + : 'a required'; + + function annotateProp(propName: string, propType: string) { + if (isPropNullable && isPropOptional) { + return `${propName}?: ?${propType}`; + } + if (isPropNullable) { + return `${propName}: ?${propType}`; + } + if (isPropOptional) { + return `${propName}?: ${propType}`; + } + return `${propName}: ${propType}`; + } + + function parseParamTypeObjectLiteralProp( + propName: string, + propType: string, + ) { + const param = parseParamType( + 'arg', + `{|${annotateProp(propName, propType)}|}`, + ); + + expect(param.typeAnnotation.type).toBe('ObjectTypeAnnotation'); + invariant( + param.typeAnnotation.type === 'ObjectTypeAnnotation', + '', + ); + + const {properties} = param.typeAnnotation; + + expect(properties).not.toBe(null); + invariant(properties != null, ''); + + expect(properties.length).toBe(1); + expect(properties[0].name).toBe(propName); + expect(properties[0].optional).toBe(isPropOptional); + expect(properties[0].typeAnnotation).not.toBe(null); + expect(properties[0].typeAnnotation.nullable).toBe( + isPropNullable, + ); + invariant(properties[0].typeAnnotation != null, ''); + + return { + ...properties[0], + typeAnnotation: properties[0].typeAnnotation, + }; + } + + describe( + (isPropNullable && isPropOptional + ? 'Nullable and Optional' + : isPropNullable + ? 'Nullable' + : isPropOptional + ? 'Optional' + : 'Required') + ' Property', + () => { + describe('Props with Primitive Types', () => { + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of primitive type '${FLOW_TYPE}'`, () => { + const prop = parseParamTypeObjectLiteralProp( + 'prop', + FLOW_TYPE, + ); + expect(prop.typeAnnotation.type).toBe(PARSED_TYPE_NAME); + }); + }); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Object'`, () => { + const prop = parseParamTypeObjectLiteralProp( + 'prop', + 'Object', + ); + expect(prop.typeAnnotation.type).toBe( + 'GenericObjectTypeAnnotation', + ); + }); + + describe('Props with Reserved Types', () => { + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of reserved type '${FLOW_TYPE}'`, () => { + const prop = parseParamTypeObjectLiteralProp( + 'prop', + FLOW_TYPE, + ); + expect(prop.typeAnnotation.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + prop.typeAnnotation.type === + 'ReservedFunctionValueTypeAnnotation', + '', + ); + + expect(prop.typeAnnotation.name).toBe(FLOW_TYPE); + }); + }); + }); + + describe('Props with Array Types', () => { + it(`should not parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array`, () => { + expect(() => + parseParamTypeObjectLiteralProp('prop', 'Array'), + ).toThrow( + new FlowGenericNotTypeParameterizedParserError( + MODULE_NAME, + 'Array', + ), + ); + }); + + function parseArrayElementType( + propName: string, + arrayElementType: string, + ) { + const property = parseParamTypeObjectLiteralProp( + 'propName', + `Array<${arrayElementType}>`, + ); + expect(property.typeAnnotation.type).toBe( + 'ArrayTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === 'ArrayTypeAnnotation', + '', + ); + + const {elementType} = property.typeAnnotation; + expect(elementType).not.toBe(null); + invariant(elementType != null, ''); + return elementType; + } + + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseArrayElementType( + 'prop', + FLOW_TYPE, + ); + + expect(elementType.type).toBe(PARSED_TYPE_NAME); + }); + }); + + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseArrayElementType( + 'prop', + FLOW_TYPE, + ); + + expect(elementType.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + elementType.type === + 'ReservedFunctionValueTypeAnnotation', + '', + ); + expect(elementType.name).toBe(FLOW_TYPE); + }); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array'`, () => { + const elementType = parseArrayElementType('prop', 'Object'); + expect(elementType.type).toBe( + 'GenericObjectTypeAnnotation', + ); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type of some array of an aliase`, () => { + const elementType = parseArrayElementType('prop', 'Animal'); + + expect(elementType.type).toBe('TypeAliasTypeAnnotation'); + invariant( + elementType.type === 'TypeAliasTypeAnnotation', + '', + ); + + expect(elementType.name).toBe('Animal'); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of 'Array<{|foo: ?string|}>'`, () => { + const elementType = parseArrayElementType( + 'prop', + '{|foo: ?string|}', + ); + + expect(elementType.type).toBe('ObjectTypeAnnotation'); + invariant(elementType.type === 'ObjectTypeAnnotation', ''); + + const {properties} = elementType; + expect(properties).not.toBe(null); + invariant(properties != null, ''); + + expect(properties[0]).not.toBe(null); + expect(properties[0].name).toBe('foo'); + expect(properties[0].typeAnnotation).not.toBe(null); + expect(properties[0].typeAnnotation?.type).toBe( + 'StringTypeAnnotation', + ); + expect(properties[0].typeAnnotation?.nullable).toBe(true); + expect(properties[0].optional).toBe(false); + }); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type '{|foo: ?string|}'`, () => { + const property = parseParamTypeObjectLiteralProp( + 'prop', + '{|foo: ?string|}', + ); + + expect(property.typeAnnotation.type).toBe( + 'ObjectTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === 'ObjectTypeAnnotation', + '', + ); + + const {properties} = property.typeAnnotation; + expect(properties).not.toBe(null); + invariant(properties != null, ''); + + expect(properties[0]).not.toBe(null); + expect(properties[0].name).toBe('foo'); + expect(properties[0].typeAnnotation).not.toBe(null); + expect(properties[0].typeAnnotation?.type).toBe( + 'StringTypeAnnotation', + ); + expect(properties[0].typeAnnotation?.nullable).toBe(true); + expect(properties[0].optional).toBe(false); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of some type alias`, () => { + const property = parseParamTypeObjectLiteralProp( + 'prop', + 'Animal', + ); + + expect(property.typeAnnotation.type).toBe( + 'TypeAliasTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === 'TypeAliasTypeAnnotation', + '', + ); + + expect(property.typeAnnotation.name).toBe('Animal'); + }); + }, + ); + }); + }, + ); + }); + }); + + describe('Return Parsing', () => { + it('should parse methods that have a return type of void', () => { + const module = parseModule(` + import type {TurboModule} from 'RCTExport'; + import * as TurboModuleRegistry from 'TurboModuleRegistry'; + export interface Spec extends TurboModule { + +useArg(): void; + } + export default TurboModuleRegistry.get('Foo'); + `); + + expect(module.properties[0]).not.toBe(null); + const {returnTypeAnnotation} = module.properties[0].typeAnnotation; + expect(returnTypeAnnotation).not.toBe(null); + expect(returnTypeAnnotation.type).toBe('VoidTypeAnnotation'); + expect(returnTypeAnnotation.nullable).toBe(false); + }); + + [true, false].forEach(IS_RETURN_TYPE_NULLABLE => { + const RETURN_TYPE_DESCRIPTION = IS_RETURN_TYPE_NULLABLE + ? 'a nullable' + : 'a non-nullable'; + const annotateRet = retType => + IS_RETURN_TYPE_NULLABLE ? `?${retType}` : retType; + + function parseReturnType(flowType: string) { + const module = parseModule(` + import type {TurboModule} from 'RCTExport'; + import * as TurboModuleRegistry from 'TurboModuleRegistry'; + type Animal = {| + name: string, + |}; + export interface Spec extends TurboModule { + +useArg(): ${annotateRet(flowType)}; + } + export default TurboModuleRegistry.get('Foo'); + `); + + expect(module.properties[0]).not.toBe(null); + const {returnTypeAnnotation} = module.properties[0].typeAnnotation; + expect(returnTypeAnnotation).not.toBe(null); + expect(returnTypeAnnotation.nullable).toBe(IS_RETURN_TYPE_NULLABLE); + return returnTypeAnnotation; + } + + describe( + IS_RETURN_TYPE_NULLABLE ? 'Nullable Returns' : 'Non-Nullable Returns', + () => { + ['Promise', 'Promise<{||}>', 'Promise<*>'].forEach( + promiseFlowType => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type '${promiseFlowType}'`, () => { + const returnTypeAnnotation = parseReturnType(promiseFlowType); + expect(returnTypeAnnotation.type).toBe( + 'GenericPromiseTypeAnnotation', + ); + }); + }, + ); + + describe('Primitive Types', () => { + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} primitive return of type '${FLOW_TYPE}'`, () => { + const returnTypeAnnotation = parseReturnType(FLOW_TYPE); + expect(returnTypeAnnotation.type).toBe(PARSED_TYPE_NAME); + }); + }); + }); + + describe('Reserved Types', () => { + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} reserved return of type '${FLOW_TYPE}'`, () => { + const returnTypeAnnotation = parseReturnType(FLOW_TYPE); + expect(returnTypeAnnotation.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + returnTypeAnnotation.type === + 'ReservedFunctionValueTypeAnnotation', + '', + ); + expect(returnTypeAnnotation.name).toBe(FLOW_TYPE); + }); + }); + }); + + describe('Array Types', () => { + it(`should not parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array'`, () => { + expect(() => parseReturnType('Array')).toThrow( + new FlowGenericNotTypeParameterizedParserError( + MODULE_NAME, + 'Array', + ), + ); + }); + + function parseArrayElementReturnType(flowType: string) { + const returnTypeAnnotation = parseReturnType( + 'Array' + (flowType != null ? `<${flowType}>` : ''), + ); + expect(returnTypeAnnotation.type).toBe('ArrayTypeAnnotation'); + invariant( + returnTypeAnnotation.type === 'ArrayTypeAnnotation', + '', + ); + + const {elementType} = returnTypeAnnotation; + expect(elementType).not.toBe(null); + invariant(elementType != null, ''); + return elementType; + } + + // TODO: Do we support nullable element types? + + describe('Primitive Element Types', () => { + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseArrayElementReturnType(FLOW_TYPE); + expect(elementType.type).toBe(PARSED_TYPE_NAME); + }); + }); + }); + + describe('Reserved Element Types', () => { + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseArrayElementReturnType(FLOW_TYPE); + expect(elementType.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + elementType.type === 'ReservedFunctionValueTypeAnnotation', + '', + ); + + expect(elementType.name).toBe(FLOW_TYPE); + }); + }); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array'`, () => { + const elementType = parseArrayElementReturnType('Object'); + expect(elementType.type).toBe('GenericObjectTypeAnnotation'); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of some array of an aliase`, () => { + const elementType = parseArrayElementReturnType('Animal'); + expect(elementType.type).toBe('TypeAliasTypeAnnotation'); + invariant(elementType.type === 'TypeAliasTypeAnnotation', ''); + expect(elementType.name).toBe('Animal'); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array<{|foo: ?string|}>'`, () => { + const elementType = parseArrayElementReturnType( + '{|foo: ?string|}', + ); + expect(elementType.type).toBe('ObjectTypeAnnotation'); + invariant(elementType.type === 'ObjectTypeAnnotation', ''); + + const {properties} = elementType; + expect(properties).not.toBe(null); + invariant(properties != null, ''); + + expect(properties[0]).not.toBe(null); + expect(properties[0].name).toBe('foo'); + expect(properties[0].typeAnnotation).not.toBe(null); + expect(properties[0].typeAnnotation?.type).toBe( + 'StringTypeAnnotation', + ); + expect(properties[0].typeAnnotation?.nullable).toBe(true); + expect(properties[0].optional).toBe(false); + }); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of some type alias`, () => { + const returnTypeAnnotation = parseReturnType('Animal'); + expect(returnTypeAnnotation.type).toBe('TypeAliasTypeAnnotation'); + invariant( + returnTypeAnnotation.type === 'TypeAliasTypeAnnotation', + '', + ); + expect(returnTypeAnnotation.name).toBe('Animal'); + }); + + it(`should not parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Function'`, () => { + expect(() => parseReturnType('Function')).toThrow( + new UnrecognizedFlowGenericParserError(MODULE_NAME, 'Function'), + ); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Object'`, () => { + const returnTypeAnnotation = parseReturnType('Object'); + expect(returnTypeAnnotation.type).toBe( + 'GenericObjectTypeAnnotation', + ); + }); + + describe('Object Literals Types', () => { + // TODO: Inexact vs exact object literals? + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an empty object literal`, () => { + const returnTypeAnnotation = parseReturnType('{||}'); + expect(returnTypeAnnotation.type).toBe('ObjectTypeAnnotation'); + invariant( + returnTypeAnnotation.type === 'ObjectTypeAnnotation', + '', + ); + + // Validate properties of object literal + expect(returnTypeAnnotation.properties).not.toBe(null); + expect(returnTypeAnnotation.properties?.length).toBe(0); + }); + + [ + {nullable: false, optional: false}, + {nullable: false, optional: true}, + {nullable: true, optional: false}, + {nullable: true, optional: true}, + ].forEach(({nullable, optional}) => { + const PROP_TYPE_DESCRIPTION = + nullable && optional + ? 'a nullable and optional' + : nullable + ? 'a nullable' + : optional + ? 'an optional' + : 'a required'; + + function annotateProp(propName, propType) { + if (nullable && optional) { + return `${propName}?: ?${propType}`; + } + if (nullable) { + return `${propName}: ?${propType}`; + } + if (optional) { + return `${propName}?: ${propType}`; + } + return `${propName}: ${propType}`; + } + + function parseObjectLiteralReturnTypeProp( + propName: string, + propType: string, + ) { + const returnTypeAnnotation = parseReturnType( + `{|${annotateProp(propName, propType)}|}`, + ); + expect(returnTypeAnnotation.type).toBe('ObjectTypeAnnotation'); + invariant( + returnTypeAnnotation.type === 'ObjectTypeAnnotation', + '', + ); + + const properties = returnTypeAnnotation.properties; + expect(properties).not.toBe(null); + invariant(properties != null, ''); + + expect(properties.length).toBe(1); + + // Validate property + const property = properties[0]; + expect(property.name).toBe(propName); + expect(property.optional).toBe(optional); + expect(property.typeAnnotation).not.toBe(null); + expect(property.typeAnnotation?.nullable).toBe(nullable); + invariant(property.typeAnnotation != null, ''); + return { + ...property, + typeAnnotation: property.typeAnnotation, + }; + } + + describe( + (nullable && optional + ? 'Nullable and Optional' + : nullable + ? 'Nullable' + : optional + ? 'Optional' + : 'Required') + ' Property', + () => { + /** + * TODO: Fill out props in promise + */ + + describe('Props with Primitive Types', () => { + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of primitive type '${FLOW_TYPE}'`, () => { + const property = parseObjectLiteralReturnTypeProp( + 'prop', + FLOW_TYPE, + ); + expect(property.typeAnnotation.type).toBe( + PARSED_TYPE_NAME, + ); + }); + }); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Object'`, () => { + const property = parseObjectLiteralReturnTypeProp( + 'prop', + 'Object', + ); + + expect(property.typeAnnotation.type).toBe( + 'GenericObjectTypeAnnotation', + ); + }); + + describe('Props with Reserved Types', () => { + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of reserved type '${FLOW_TYPE}'`, () => { + const property = parseObjectLiteralReturnTypeProp( + 'prop', + FLOW_TYPE, + ); + + expect(property.typeAnnotation.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === + 'ReservedFunctionValueTypeAnnotation', + '', + ); + + expect(property.typeAnnotation.name).toBe(FLOW_TYPE); + }); + }); + }); + + describe('Props with Array Types', () => { + it(`should not parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array`, () => { + expect(() => + parseObjectLiteralReturnTypeProp('prop', 'Array'), + ).toThrow( + new FlowGenericNotTypeParameterizedParserError( + MODULE_NAME, + 'Array', + ), + ); + }); + + function parseArrayElementType( + propName: string, + arrayElementType: string, + ) { + const property = parseObjectLiteralReturnTypeProp( + propName, + `Array<${arrayElementType}>`, + ); + expect(property.name).toBe(propName); + expect(property.typeAnnotation.type).toBe( + 'ArrayTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === 'ArrayTypeAnnotation', + '', + ); + + const {elementType} = property.typeAnnotation; + expect(elementType).not.toBe(null); + invariant(elementType != null, ''); + return elementType; + } + + PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseArrayElementType( + 'prop', + FLOW_TYPE, + ); + expect(elementType.type).toBe(PARSED_TYPE_NAME); + }); + }); + + RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { + const elementType = parseArrayElementType( + 'prop', + FLOW_TYPE, + ); + expect(elementType.type).toBe( + 'ReservedFunctionValueTypeAnnotation', + ); + invariant( + elementType.type === + 'ReservedFunctionValueTypeAnnotation', + '', + ); + + expect(elementType.name).toBe(FLOW_TYPE); + }); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array'`, () => { + const elementType = parseArrayElementType( + 'prop', + 'Object', + ); + expect(elementType).not.toBe(null); + expect(elementType.type).toBe( + 'GenericObjectTypeAnnotation', + ); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type of some array of an aliase`, () => { + const elementType = parseArrayElementType( + 'prop', + 'Animal', + ); + expect(elementType.type).toBe('TypeAliasTypeAnnotation'); + invariant( + elementType.type === 'TypeAliasTypeAnnotation', + '', + ); + expect(elementType.name).toBe('Animal'); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<{|foo: ?string|}>'`, () => { + const elementType = parseArrayElementType( + 'prop', + '{|foo: ?string|}', + ); + expect(elementType.type).toBe('ObjectTypeAnnotation'); + invariant( + elementType.type === 'ObjectTypeAnnotation', + '', + ); + + const {properties} = elementType; + invariant(properties != null, ''); + expect(properties).not.toBe(null); + expect(properties[0]).not.toBe(null); + expect(properties[0].name).toBe('foo'); + expect(properties[0].optional).toBe(false); + + expect(properties[0].typeAnnotation).not.toBe(null); + invariant(properties[0].typeAnnotation != null, ''); + + expect(properties[0].typeAnnotation.type).toBe( + 'StringTypeAnnotation', + ); + expect(properties[0].typeAnnotation.nullable).toBe(true); + }); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of '{|foo: ?string|}'`, () => { + const property = parseObjectLiteralReturnTypeProp( + 'prop', + '{|foo: ?string|}', + ); + + expect(property.typeAnnotation.type).toBe( + 'ObjectTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === 'ObjectTypeAnnotation', + '', + ); + + const {properties} = property.typeAnnotation; + + expect(properties).not.toBe(null); + invariant(properties != null, ''); + + expect(properties[0]).not.toBe(null); + expect(properties[0].name).toBe('foo'); + expect(properties[0].optional).toBe(false); + + expect(properties[0].typeAnnotation).not.toBe(null); + invariant(properties[0].typeAnnotation != null, ''); + + expect(properties[0].typeAnnotation.type).toBe( + 'StringTypeAnnotation', + ); + expect(properties[0].typeAnnotation.nullable).toBe(true); + }); + + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of some type alias`, () => { + const property = parseObjectLiteralReturnTypeProp( + 'prop', + 'Animal', + ); + + expect(property.typeAnnotation.type).toBe( + 'TypeAliasTypeAnnotation', + ); + invariant( + property.typeAnnotation.type === + 'TypeAliasTypeAnnotation', + '', + ); + + expect(property.typeAnnotation.name).toBe('Animal'); + }); + }, + ); + }); + }); + }, + ); + }); + }); +}); + +function parseModule(source) { + const schema = parseString(source, `Native${MODULE_NAME}.js`); + const {nativeModules} = schema.modules.NativeFoo; + invariant( + nativeModules, + "'nativeModules' in Spec NativeFoo shouldn't be null", + ); + return nativeModules.Foo; +} diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-test.js b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-snapshot-test.js similarity index 100% rename from packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-test.js rename to packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-snapshot-test.js From 572e1da889f2db46360c8673a6b581950384240e Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 17/52] Fix type alias nullability resolution in module parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Consider this case: ``` type Animal = ?{| name: string, |}; type B = Animal export interface Spec extends TurboModule { +greet: (animal: B) => void; } ``` The generated output for this spec is: ``` namespace JS { namespace NativeSampleTurboModule { struct Animal { NSString *name() const; Animal(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } protocol NativeSampleTurboModuleSpec - (void)greet:(JS::NativeSampleTurboModule::Animal &)animal; end ``` Observations: 1. The codegen looks as though we wrote `+greet: (animal: ?Animal) => void;` as opposed to `+greet: (animal: B) => void;` 2. The generated struct is called `Animal`, not `B`. ## After this diff Whenever we detect a usage of a type alias, we recursively resolve it, keeping a track of whether the resolution will be nullable. In this example, we follow B to Animal, and then Animal to ?{|name: string|}. Then, we: 1. Replace the `B` in `+greet: (animal: B) => void;` with `?Animal`, 2. Pretend that `Animal = {|name: string|}`. Why do we make all type alias RHSs required? 2. This design is simpler than managing nullability in both the type alias usage, and the type alias RHS. 3. What does it mean for a C++ struct, which is what this type alias RHS will generate, to be nullable? ¯\_(ツ)_/¯. Nullability is a concept that only makes sense when talking about instances (i.e: usages) of the C++ structs. Hence, it's better to manage nullability within the actual TypeAliasTypeAnnotation nodes, and not the associated ObjectTypeAnnotations. ## Other Changes - Whenever we use the `Animal` type-alias, the e2e jest tests validate that the type alias exists in the module schema. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23225934 fbshipit-source-id: 8316dea2ec6e2d50cad90e178963c6264044f7b7 --- .../react-native-codegen/src/CodegenSchema.js | 20 +- .../__tests__/module-parser-e2e-test.js | 243 +++++++++++++----- .../src/parsers/flow/modules/index.js | 75 ++++-- .../src/parsers/flow/utils.js | 23 +- 4 files changed, 258 insertions(+), 103 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 425662967a2c6e..f0d8d30d14d512 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -266,7 +266,11 @@ export type NativeModuleSchema = $ReadOnly<{| |}>; export type NativeModuleAliasMap = { - [aliasName: string]: NativeModuleObjectTypeAnnotation, + [aliasName: string]: $ReadOnly<{| + type: 'ObjectTypeAnnotation', + properties: $ReadOnlyArray, + nullable: false, + |}>, }; export type NativeModulePropertySchema = $ReadOnly<{| @@ -290,16 +294,16 @@ export type NativeModuleFunctionTypeAnnotation = $ReadOnly<{| export type NativeModuleObjectTypeAnnotation = $ReadOnly<{| type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray< - $ReadOnly<{| - optional: boolean, - name: string, - typeAnnotation: NativeModuleParamTypeAnnotation, - |}>, - >, + properties: $ReadOnlyArray, nullable: boolean, |}>; +export type NativeModuleObjectTypeAnnotationPropertySchema = $ReadOnly<{| + optional: boolean, + name: string, + typeAnnotation: NativeModuleBaseTypeAnnotation, +|}>; + export type NativeModuleBaseTypeAnnotation = | $ReadOnly<{| type: 'StringTypeAnnotation', diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js index 734e456922f510..e4647258fe32e3 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js @@ -8,7 +8,10 @@ * @format */ -import type {ReservedFunctionValueTypeName} from '../../../../CodegenSchema'; +import type { + ReservedFunctionValueTypeName, + NativeModuleSchema, +} from '../../../../CodegenSchema'; const {parseString} = require('../../index.js'); const { FlowGenericNotTypeParameterizedParserError, @@ -41,6 +44,30 @@ const RESERVED_FUNCTION_VALUE_TYPE_NAME: $ReadOnlyArray { describe('Parameter Parsing', () => { it("should fail parsing when a method has an parameter of type 'any'", () => { @@ -111,9 +138,7 @@ describe('Flow Module Parser', () => { import type {TurboModule} from 'RCTExport'; import * as TurboModuleRegistry from 'TurboModuleRegistry'; - type Animal = {| - name: string, - |}; + ${TYPE_ALIAS_DECLARATIONS} export interface Spec extends TurboModule { +useArg(${annotateArg(paramName, paramType)}): void; @@ -128,7 +153,7 @@ describe('Flow Module Parser', () => { expect(param.optional).toBe(optional); expect(param.typeAnnotation.nullable).toBe(nullable); - return param; + return [param, module]; } describe( @@ -149,14 +174,14 @@ describe('Flow Module Parser', () => { describe('Primitive types', () => { PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} primitive parameter of type '${FLOW_TYPE}'`, () => { - const param = parseParamType('arg', FLOW_TYPE); + const [param] = parseParamType('arg', FLOW_TYPE); expect(param.typeAnnotation.type).toBe(PARSED_TYPE_NAME); }); }); }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Object'`, () => { - const param = parseParamType('arg', 'Object'); + const [param] = parseParamType('arg', 'Object'); expect(param.typeAnnotation.type).toBe( 'GenericObjectTypeAnnotation', ); @@ -165,7 +190,7 @@ describe('Flow Module Parser', () => { describe('Reserved Types', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of reserved type '${FLOW_TYPE}'`, () => { - const param = parseParamType('arg', FLOW_TYPE); + const [param] = parseParamType('arg', FLOW_TYPE); expect(param.typeAnnotation.type).toBe( 'ReservedFunctionValueTypeAnnotation', @@ -195,7 +220,10 @@ describe('Flow Module Parser', () => { paramName: string, paramType: string, ) { - const param = parseParamType(paramName, `Array<${paramType}>`); + const [param, module] = parseParamType( + paramName, + `Array<${paramType}>`, + ); expect(param.typeAnnotation.type).toBe('ArrayTypeAnnotation'); invariant( @@ -205,7 +233,7 @@ describe('Flow Module Parser', () => { expect(param.typeAnnotation.elementType).not.toBe(null); invariant(param.typeAnnotation.elementType != null, ''); - return param.typeAnnotation.elementType; + return [param.typeAnnotation.elementType, module]; } // TODO: Do we support nullable element types? @@ -213,7 +241,7 @@ describe('Flow Module Parser', () => { describe('Primitive Element Types', () => { PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseParamArrayElementType( + const [elementType] = parseParamArrayElementType( 'arg', FLOW_TYPE, ); @@ -225,7 +253,7 @@ describe('Flow Module Parser', () => { describe('Reserved Element Types', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseParamArrayElementType( + const [elementType] = parseParamArrayElementType( 'arg', FLOW_TYPE, ); @@ -243,20 +271,24 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array'`, () => { - const elementType = parseParamArrayElementType('arg', 'Object'); + const [elementType] = parseParamArrayElementType('arg', 'Object'); expect(elementType.type).toBe('GenericObjectTypeAnnotation'); }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of some array of an alias`, () => { - const elementType = parseParamArrayElementType('arg', 'Animal'); + const [elementType, module] = parseParamArrayElementType( + 'arg', + 'Animal', + ); expect(elementType.type).toBe('TypeAliasTypeAnnotation'); invariant(elementType.type === 'TypeAliasTypeAnnotation', ''); expect(elementType.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter of type 'Array<{|foo: ?string|}>'`, () => { - const elementType = parseParamArrayElementType( + const [elementType] = parseParamArrayElementType( 'arg', '{|foo: ?string|}', ); @@ -281,7 +313,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of some type alias`, () => { - const param = parseParamType('arg', 'Animal'); + const [param, module] = parseParamType('arg', 'Animal'); expect(param.typeAnnotation.type).toBe('TypeAliasTypeAnnotation'); invariant( param.typeAnnotation.type === 'TypeAliasTypeAnnotation', @@ -289,6 +321,54 @@ describe('Flow Module Parser', () => { ); expect(param.typeAnnotation.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of some type alias that points to another type alias`, () => { + const [param, module] = parseParamType('arg', 'AnimalPointer'); + expect(param.typeAnnotation.type).toBe('TypeAliasTypeAnnotation'); + invariant( + param.typeAnnotation.type === 'TypeAliasTypeAnnotation', + '', + ); + + expect(param.typeAnnotation.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); + }); + + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of some type alias that points to another nullable type alias`, () => { + const module = parseModule(` + import type {TurboModule} from 'RCTExport'; + import * as TurboModuleRegistry from 'TurboModuleRegistry'; + + type Animal = ?{| + name: string, + |}; + + type AnimalPointer = Animal; + + export interface Spec extends TurboModule { + +useArg(${annotateArg('arg', 'AnimalPointer')}): void; + } + export default TurboModuleRegistry.get('Foo'); + `); + + expect(module.properties[0]).not.toBe(null); + const param = module.properties[0].typeAnnotation.params[0]; + expect(param.name).toBe('arg'); + expect(param.optional).toBe(optional); + + // The TypeAliasAnnotation is called Animal, and is nullable + expect(param.typeAnnotation.type).toBe('TypeAliasTypeAnnotation'); + invariant( + param.typeAnnotation.type === 'TypeAliasTypeAnnotation', + '', + ); + expect(param.typeAnnotation.name).toBe('Animal'); + expect(param.typeAnnotation.nullable).toBe(true); + + // The Animal type alias RHS is valid, and non-null + expectAnimalTypeAliasToExist(module); }); [ @@ -323,7 +403,7 @@ describe('Flow Module Parser', () => { propName: string, propType: string, ) { - const param = parseParamType( + const [param, module] = parseParamType( 'arg', `{|${annotateProp(propName, propType)}|}`, ); @@ -348,10 +428,13 @@ describe('Flow Module Parser', () => { ); invariant(properties[0].typeAnnotation != null, ''); - return { - ...properties[0], - typeAnnotation: properties[0].typeAnnotation, - }; + return [ + { + ...properties[0], + typeAnnotation: properties[0].typeAnnotation, + }, + module, + ]; } describe( @@ -366,7 +449,7 @@ describe('Flow Module Parser', () => { describe('Props with Primitive Types', () => { PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of primitive type '${FLOW_TYPE}'`, () => { - const prop = parseParamTypeObjectLiteralProp( + const [prop] = parseParamTypeObjectLiteralProp( 'prop', FLOW_TYPE, ); @@ -376,7 +459,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Object'`, () => { - const prop = parseParamTypeObjectLiteralProp( + const [prop] = parseParamTypeObjectLiteralProp( 'prop', 'Object', ); @@ -388,7 +471,7 @@ describe('Flow Module Parser', () => { describe('Props with Reserved Types', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of reserved type '${FLOW_TYPE}'`, () => { - const prop = parseParamTypeObjectLiteralProp( + const [prop] = parseParamTypeObjectLiteralProp( 'prop', FLOW_TYPE, ); @@ -422,7 +505,7 @@ describe('Flow Module Parser', () => { propName: string, arrayElementType: string, ) { - const property = parseParamTypeObjectLiteralProp( + const [property, module] = parseParamTypeObjectLiteralProp( 'propName', `Array<${arrayElementType}>`, ); @@ -437,12 +520,12 @@ describe('Flow Module Parser', () => { const {elementType} = property.typeAnnotation; expect(elementType).not.toBe(null); invariant(elementType != null, ''); - return elementType; + return [elementType, module]; } PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', FLOW_TYPE, ); @@ -453,7 +536,7 @@ describe('Flow Module Parser', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', FLOW_TYPE, ); @@ -471,14 +554,20 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array'`, () => { - const elementType = parseArrayElementType('prop', 'Object'); + const [elementType] = parseArrayElementType( + 'prop', + 'Object', + ); expect(elementType.type).toBe( 'GenericObjectTypeAnnotation', ); }); - it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type of some array of an aliase`, () => { - const elementType = parseArrayElementType('prop', 'Animal'); + it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type of some array of an alias`, () => { + const [elementType, module] = parseArrayElementType( + 'prop', + 'Animal', + ); expect(elementType.type).toBe('TypeAliasTypeAnnotation'); invariant( @@ -487,10 +576,11 @@ describe('Flow Module Parser', () => { ); expect(elementType.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of 'Array<{|foo: ?string|}>'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', '{|foo: ?string|}', ); @@ -514,7 +604,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type '{|foo: ?string|}'`, () => { - const property = parseParamTypeObjectLiteralProp( + const [property] = parseParamTypeObjectLiteralProp( 'prop', '{|foo: ?string|}', ); @@ -542,7 +632,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${PARAM_TYPE_DESCRIPTION} parameter type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of some type alias`, () => { - const property = parseParamTypeObjectLiteralProp( + const [property, module] = parseParamTypeObjectLiteralProp( 'prop', 'Animal', ); @@ -556,6 +646,7 @@ describe('Flow Module Parser', () => { ); expect(property.typeAnnotation.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); }, ); @@ -594,9 +685,9 @@ describe('Flow Module Parser', () => { const module = parseModule(` import type {TurboModule} from 'RCTExport'; import * as TurboModuleRegistry from 'TurboModuleRegistry'; - type Animal = {| - name: string, - |}; + + ${TYPE_ALIAS_DECLARATIONS} + export interface Spec extends TurboModule { +useArg(): ${annotateRet(flowType)}; } @@ -607,7 +698,7 @@ describe('Flow Module Parser', () => { const {returnTypeAnnotation} = module.properties[0].typeAnnotation; expect(returnTypeAnnotation).not.toBe(null); expect(returnTypeAnnotation.nullable).toBe(IS_RETURN_TYPE_NULLABLE); - return returnTypeAnnotation; + return [returnTypeAnnotation, module]; } describe( @@ -616,7 +707,7 @@ describe('Flow Module Parser', () => { ['Promise', 'Promise<{||}>', 'Promise<*>'].forEach( promiseFlowType => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type '${promiseFlowType}'`, () => { - const returnTypeAnnotation = parseReturnType(promiseFlowType); + const [returnTypeAnnotation] = parseReturnType(promiseFlowType); expect(returnTypeAnnotation.type).toBe( 'GenericPromiseTypeAnnotation', ); @@ -627,7 +718,7 @@ describe('Flow Module Parser', () => { describe('Primitive Types', () => { PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} primitive return of type '${FLOW_TYPE}'`, () => { - const returnTypeAnnotation = parseReturnType(FLOW_TYPE); + const [returnTypeAnnotation] = parseReturnType(FLOW_TYPE); expect(returnTypeAnnotation.type).toBe(PARSED_TYPE_NAME); }); }); @@ -636,7 +727,7 @@ describe('Flow Module Parser', () => { describe('Reserved Types', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} reserved return of type '${FLOW_TYPE}'`, () => { - const returnTypeAnnotation = parseReturnType(FLOW_TYPE); + const [returnTypeAnnotation] = parseReturnType(FLOW_TYPE); expect(returnTypeAnnotation.type).toBe( 'ReservedFunctionValueTypeAnnotation', ); @@ -661,7 +752,7 @@ describe('Flow Module Parser', () => { }); function parseArrayElementReturnType(flowType: string) { - const returnTypeAnnotation = parseReturnType( + const [returnTypeAnnotation, module] = parseReturnType( 'Array' + (flowType != null ? `<${flowType}>` : ''), ); expect(returnTypeAnnotation.type).toBe('ArrayTypeAnnotation'); @@ -673,7 +764,7 @@ describe('Flow Module Parser', () => { const {elementType} = returnTypeAnnotation; expect(elementType).not.toBe(null); invariant(elementType != null, ''); - return elementType; + return [elementType, module]; } // TODO: Do we support nullable element types? @@ -681,7 +772,9 @@ describe('Flow Module Parser', () => { describe('Primitive Element Types', () => { PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseArrayElementReturnType(FLOW_TYPE); + const [elementType, module] = parseArrayElementReturnType( + FLOW_TYPE, + ); expect(elementType.type).toBe(PARSED_TYPE_NAME); }); }); @@ -690,7 +783,7 @@ describe('Flow Module Parser', () => { describe('Reserved Element Types', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseArrayElementReturnType(FLOW_TYPE); + const [elementType] = parseArrayElementReturnType(FLOW_TYPE); expect(elementType.type).toBe( 'ReservedFunctionValueTypeAnnotation', ); @@ -705,19 +798,22 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array'`, () => { - const elementType = parseArrayElementReturnType('Object'); + const [elementType] = parseArrayElementReturnType('Object'); expect(elementType.type).toBe('GenericObjectTypeAnnotation'); }); - it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of some array of an aliase`, () => { - const elementType = parseArrayElementReturnType('Animal'); + it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of some array of an alias`, () => { + const [elementType, module] = parseArrayElementReturnType( + 'Animal', + ); expect(elementType.type).toBe('TypeAliasTypeAnnotation'); invariant(elementType.type === 'TypeAliasTypeAnnotation', ''); expect(elementType.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Array<{|foo: ?string|}>'`, () => { - const elementType = parseArrayElementReturnType( + const [elementType] = parseArrayElementReturnType( '{|foo: ?string|}', ); expect(elementType.type).toBe('ObjectTypeAnnotation'); @@ -739,13 +835,14 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of some type alias`, () => { - const returnTypeAnnotation = parseReturnType('Animal'); + const [returnTypeAnnotation, module] = parseReturnType('Animal'); expect(returnTypeAnnotation.type).toBe('TypeAliasTypeAnnotation'); invariant( returnTypeAnnotation.type === 'TypeAliasTypeAnnotation', '', ); expect(returnTypeAnnotation.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); it(`should not parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Function'`, () => { @@ -755,7 +852,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type 'Object'`, () => { - const returnTypeAnnotation = parseReturnType('Object'); + const [returnTypeAnnotation] = parseReturnType('Object'); expect(returnTypeAnnotation.type).toBe( 'GenericObjectTypeAnnotation', ); @@ -765,7 +862,7 @@ describe('Flow Module Parser', () => { // TODO: Inexact vs exact object literals? it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an empty object literal`, () => { - const returnTypeAnnotation = parseReturnType('{||}'); + const [returnTypeAnnotation] = parseReturnType('{||}'); expect(returnTypeAnnotation.type).toBe('ObjectTypeAnnotation'); invariant( returnTypeAnnotation.type === 'ObjectTypeAnnotation', @@ -809,7 +906,7 @@ describe('Flow Module Parser', () => { propName: string, propType: string, ) { - const returnTypeAnnotation = parseReturnType( + const [returnTypeAnnotation, module] = parseReturnType( `{|${annotateProp(propName, propType)}|}`, ); expect(returnTypeAnnotation.type).toBe('ObjectTypeAnnotation'); @@ -831,10 +928,13 @@ describe('Flow Module Parser', () => { expect(property.typeAnnotation).not.toBe(null); expect(property.typeAnnotation?.nullable).toBe(nullable); invariant(property.typeAnnotation != null, ''); - return { - ...property, - typeAnnotation: property.typeAnnotation, - }; + return [ + { + ...property, + typeAnnotation: property.typeAnnotation, + }, + module, + ]; } describe( @@ -853,7 +953,7 @@ describe('Flow Module Parser', () => { describe('Props with Primitive Types', () => { PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of primitive type '${FLOW_TYPE}'`, () => { - const property = parseObjectLiteralReturnTypeProp( + const [property] = parseObjectLiteralReturnTypeProp( 'prop', FLOW_TYPE, ); @@ -865,7 +965,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Object'`, () => { - const property = parseObjectLiteralReturnTypeProp( + const [property] = parseObjectLiteralReturnTypeProp( 'prop', 'Object', ); @@ -878,7 +978,7 @@ describe('Flow Module Parser', () => { describe('Props with Reserved Types', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of reserved type '${FLOW_TYPE}'`, () => { - const property = parseObjectLiteralReturnTypeProp( + const [property] = parseObjectLiteralReturnTypeProp( 'prop', FLOW_TYPE, ); @@ -913,7 +1013,10 @@ describe('Flow Module Parser', () => { propName: string, arrayElementType: string, ) { - const property = parseObjectLiteralReturnTypeProp( + const [ + property, + module, + ] = parseObjectLiteralReturnTypeProp( propName, `Array<${arrayElementType}>`, ); @@ -929,12 +1032,12 @@ describe('Flow Module Parser', () => { const {elementType} = property.typeAnnotation; expect(elementType).not.toBe(null); invariant(elementType != null, ''); - return elementType; + return [elementType, module]; } PRIMITIVES.forEach(([FLOW_TYPE, PARSED_TYPE_NAME]) => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', FLOW_TYPE, ); @@ -944,7 +1047,7 @@ describe('Flow Module Parser', () => { RESERVED_FUNCTION_VALUE_TYPE_NAME.forEach(FLOW_TYPE => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<${FLOW_TYPE}>'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', FLOW_TYPE, ); @@ -962,7 +1065,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', 'Object', ); @@ -973,7 +1076,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type of some array of an aliase`, () => { - const elementType = parseArrayElementType( + const [elementType, module] = parseArrayElementType( 'prop', 'Animal', ); @@ -983,10 +1086,11 @@ describe('Flow Module Parser', () => { '', ); expect(elementType.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of type 'Array<{|foo: ?string|}>'`, () => { - const elementType = parseArrayElementType( + const [elementType] = parseArrayElementType( 'prop', '{|foo: ?string|}', ); @@ -1014,7 +1118,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of '{|foo: ?string|}'`, () => { - const property = parseObjectLiteralReturnTypeProp( + const [property] = parseObjectLiteralReturnTypeProp( 'prop', '{|foo: ?string|}', ); @@ -1046,7 +1150,7 @@ describe('Flow Module Parser', () => { }); it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return type of an object literal with ${PROP_TYPE_DESCRIPTION} prop of some type alias`, () => { - const property = parseObjectLiteralReturnTypeProp( + const [property, module] = parseObjectLiteralReturnTypeProp( 'prop', 'Animal', ); @@ -1061,6 +1165,7 @@ describe('Flow Module Parser', () => { ); expect(property.typeAnnotation.name).toBe('Animal'); + expectAnimalTypeAliasToExist(module); }); }, ); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 98dc32c5abdba1..31de4e511f8e85 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -40,10 +40,11 @@ function translateTypeAnnotation( types: TypeDeclarationMap, aliasMap: NativeModuleAliasMap, ): NativeModuleTypeAnnotation { - const {nullable, typeAnnotation} = resolveTypeAnnotation( - flowTypeAnnotation, - types, - ); + const { + nullable, + typeAnnotation, + typeAliasResolutionStatus, + } = resolveTypeAnnotation(flowTypeAnnotation, types); switch (typeAnnotation.type) { case 'GenericTypeAnnotation': { @@ -161,8 +162,7 @@ function translateTypeAnnotation( } } case 'ObjectTypeAnnotation': { - const objectTypeAnnotation = { - nullable, + const objectTypeAnnotationPartial = { type: 'ObjectTypeAnnotation', properties: typeAnnotation.properties.map(property => { const {optional} = property; @@ -179,30 +179,55 @@ function translateTypeAnnotation( }), }; - if (flowTypeAnnotation.type === 'GenericTypeAnnotation') { - aliasMap[flowTypeAnnotation.id.name] = objectTypeAnnotation; + if (!typeAliasResolutionStatus.successful) { return { - nullable: false, - type: 'TypeAliasTypeAnnotation', - name: flowTypeAnnotation.id.name, + nullable, + ...objectTypeAnnotationPartial, }; } - if ( - flowTypeAnnotation.type === 'NullableTypeAnnotation' && - flowTypeAnnotation.typeAnnotation.type === 'GenericTypeAnnotation' - ) { - aliasMap[ - flowTypeAnnotation.typeAnnotation.id.name - ] = objectTypeAnnotation; - return { - nullable: true, - type: 'TypeAliasTypeAnnotation', - name: flowTypeAnnotation.typeAnnotation.id.name, - }; - } + /** + * All aliases RHS are required. + */ + aliasMap[typeAliasResolutionStatus.aliasName] = { + nullable: false, + ...objectTypeAnnotationPartial, + }; - return objectTypeAnnotation; + /** + * Nullability of type aliases is transitive. + * + * Consider this case: + * + * type Animal = ?{| + * name: string, + * |}; + * + * type B = Animal + * + * export interface Spec extends TurboModule { + * +greet: (animal: B) => void; + * } + * + * In this case, we follow B to Animal, and then Animal to ?{|name: string|}. + * + * We: + * 1. Replace `+greet: (animal: B) => void;` with `+greet: (animal: ?Animal) => void;`, + * 2. Pretend that Animal = {|name: string|}. + * + * Why do we do this? + * 1. In ObjC, we need to generate a struct called Animal, not B. + * 2. This design is simpler than managing nullability within both the type alias usage, and the type alias RHS. + * 3. What does it mean for a C++ struct, which is what this type alias RHS will generate, to be nullable? ¯\_(ツ)_/¯ + * Nullability is a concept that only makes sense when talking about instances (i.e: usages) of the C++ structs. + * Hence, it's better to manage nullability within the actual TypeAliasTypeAnnotation nodes, and not the + * associated ObjectTypeAnnotations. + */ + return { + nullable: nullable, + type: 'TypeAliasTypeAnnotation', + name: typeAliasResolutionStatus.aliasName, + }; } case 'BooleanTypeAnnotation': { return { diff --git a/packages/react-native-codegen/src/parsers/flow/utils.js b/packages/react-native-codegen/src/parsers/flow/utils.js index 87ec1894c068db..15b13c5949975a 100644 --- a/packages/react-native-codegen/src/parsers/flow/utils.js +++ b/packages/react-native-codegen/src/parsers/flow/utils.js @@ -25,11 +25,24 @@ export type ASTNode = Object; const invariant = require('invariant'); +type TypeAliasResolutionStatus = + | $ReadOnly<{| + successful: true, + aliasName: string, + |}> + | $ReadOnly<{| + successful: false, + |}>; + function resolveTypeAnnotation( // TODO(T71778680): This is an Flow TypeAnnotation. Flow-type this typeAnnotation: $FlowFixMe, types: TypeDeclarationMap, -): {nullable: boolean, typeAnnotation: $FlowFixMe} { +): { + nullable: boolean, + typeAnnotation: $FlowFixMe, + typeAliasResolutionStatus: TypeAliasResolutionStatus, +} { invariant( typeAnnotation != null, 'resolveTypeAnnotation(): typeAnnotation cannot be null', @@ -37,12 +50,19 @@ function resolveTypeAnnotation( let node = typeAnnotation; let nullable = false; + let typeAliasResolutionStatus: TypeAliasResolutionStatus = { + successful: false, + }; for (;;) { if (node.type === 'NullableTypeAnnotation') { nullable = true; node = node.typeAnnotation; } else if (node.type === 'GenericTypeAnnotation') { + typeAliasResolutionStatus = { + successful: true, + aliasName: node.id.name, + }; const resolvedTypeAnnotation = types[node.id.name]; if (resolvedTypeAnnotation == null) { break; @@ -61,6 +81,7 @@ function resolveTypeAnnotation( return { nullable: nullable, typeAnnotation: node, + typeAliasResolutionStatus, }; } From 1194a36efa286469284481b945cb1a165d368f69 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 18/52] Export module type annotations from CodegenSchema Summary: This diff has a few changes: - All type annotations are now declared top-level, and exported from `CodegenSchema.js`. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23616473 fbshipit-source-id: 1509c304305e56674bd76c44bc49f755dfeaa332 --- .../react-native-codegen/src/CodegenSchema.js | 156 +++++++++++------- 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index f0d8d30d14d512..2b26e7c0844814 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -258,6 +258,10 @@ export type SchemaType = $ReadOnly<{| /** * NativeModule Types + * + * TODO(T71923114): Remove nullable from NativeModule type annotations. + * This is necessary for us to start unifying the notion of a "type + * annotation" across the codegen schema as a whole. */ export type NativeModuleSchema = $ReadOnly<{| // We only support aliases to Objects @@ -279,12 +283,6 @@ export type NativeModulePropertySchema = $ReadOnly<{| typeAnnotation: NativeModuleFunctionTypeAnnotation, |}>; -export type NativeModuleMethodParamSchema = $ReadOnly<{| - name: string, - optional: boolean, - typeAnnotation: NativeModuleParamTypeAnnotation, -|}>; - export type NativeModuleFunctionTypeAnnotation = $ReadOnly<{| type: 'FunctionTypeAnnotation', params: $ReadOnlyArray, @@ -292,6 +290,12 @@ export type NativeModuleFunctionTypeAnnotation = $ReadOnly<{| nullable: boolean, |}>; +export type NativeModuleMethodParamSchema = $ReadOnly<{| + name: string, + optional: boolean, + typeAnnotation: NativeModuleParamTypeAnnotation, +|}>; + export type NativeModuleObjectTypeAnnotation = $ReadOnly<{| type: 'ObjectTypeAnnotation', properties: $ReadOnlyArray, @@ -304,67 +308,86 @@ export type NativeModuleObjectTypeAnnotationPropertySchema = $ReadOnly<{| typeAnnotation: NativeModuleBaseTypeAnnotation, |}>; +export type NativeModuleArrayTypeAnnotation = $ReadOnly<{| + type: 'ArrayTypeAnnotation', + /** + * TODO(T72031674): Migrate all our NativeModule specs to not use + * invalid Array ElementTypes. Then, make the elementType required. + */ + elementType?: NativeModuleBaseTypeAnnotation, + nullable: boolean, +|}>; + +export type NativeModuleStringTypeAnnotation = $ReadOnly<{| + type: 'StringTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleNumberTypeAnnotation = $ReadOnly<{| + type: 'NumberTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleInt32TypeAnnotation = $ReadOnly<{| + type: 'Int32TypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleDoubleTypeAnnotation = $ReadOnly<{| + type: 'DoubleTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleFloatTypeAnnotation = $ReadOnly<{| + type: 'FloatTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleBooleanTypeAnnotation = $ReadOnly<{| + type: 'BooleanTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleGenericObjectTypeAnnotation = $ReadOnly<{| + type: 'GenericObjectTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleReservedFunctionValueTypeAnnotation = $ReadOnly<{| + type: 'ReservedFunctionValueTypeAnnotation', + name: ReservedFunctionValueTypeName, + nullable: boolean, +|}>; + +export type NativeModuleTypeAliasTypeAnnotation = $ReadOnly<{| + type: 'TypeAliasTypeAnnotation', + name: string, + nullable: boolean, +|}>; + +export type NativeModulePromiseTypeAnnotation = $ReadOnly<{| + type: 'GenericPromiseTypeAnnotation', + nullable: boolean, +|}>; + +export type NativeModuleVoidTypeAnnotation = $ReadOnly<{| + type: 'VoidTypeAnnotation', + nullable: boolean, +|}>; + export type NativeModuleBaseTypeAnnotation = - | $ReadOnly<{| - type: 'StringTypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'NumberTypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'Int32TypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'DoubleTypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'FloatTypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'BooleanTypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'GenericObjectTypeAnnotation', - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'ReservedFunctionValueTypeAnnotation', - name: ReservedFunctionValueTypeName, - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'ArrayTypeAnnotation', - /** - * TODO(T72031674): Migrate all our NativeModule specs to not use - * invalid Array ElementTypes. Then, make the elementType required. - */ - elementType?: NativeModuleBaseTypeAnnotation, - nullable: boolean, - |}> - | $ReadOnly<{| - type: 'TypeAliasTypeAnnotation', - name: string, - nullable: boolean, - |}> + | NativeModuleStringTypeAnnotation + | NativeModuleNumberTypeAnnotation + | NativeModuleInt32TypeAnnotation + | NativeModuleDoubleTypeAnnotation + | NativeModuleFloatTypeAnnotation + | NativeModuleBooleanTypeAnnotation + | NativeModuleGenericObjectTypeAnnotation + | NativeModuleReservedFunctionValueTypeAnnotation + | NativeModuleTypeAliasTypeAnnotation + | NativeModuleArrayTypeAnnotation | NativeModuleObjectTypeAnnotation; -export type NativeModuleParamOnlyTypeAnnotation = NativeModuleFunctionTypeAnnotation; -export type NativeModuleReturnOnlyTypeAnnotation = - | $ReadOnly<{| - nullable: boolean, - type: 'GenericPromiseTypeAnnotation', - |}> - | $ReadOnly<{| - nullable: boolean, - type: 'VoidTypeAnnotation', - |}>; - export type NativeModuleParamTypeAnnotation = | NativeModuleBaseTypeAnnotation | NativeModuleParamOnlyTypeAnnotation; @@ -378,4 +401,9 @@ export type NativeModuleTypeAnnotation = | NativeModuleParamOnlyTypeAnnotation | NativeModuleReturnOnlyTypeAnnotation; +type NativeModuleParamOnlyTypeAnnotation = NativeModuleFunctionTypeAnnotation; +type NativeModuleReturnOnlyTypeAnnotation = + | NativeModulePromiseTypeAnnotation + | NativeModuleVoidTypeAnnotation; + export type ReservedFunctionValueTypeName = 'RootTag'; // Union with more custom types. From 2e0fb693657aa1cca46857f78fffb1a47ee5383c Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 19/52] Refactor: Introduce Required generic type Summary: This diff introduces a `Required` generic type in CodegenSchema. Why? NativeModule aliase RHSs are basically ObjectTypeAnnotations but they have `nullable` fixed to `false`. This generic type reduces duplication in the schema flow types. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D23645208 fbshipit-source-id: da984f64fa17d8533a3ea74b132ce10aae9aa7ed --- .../react-native-codegen/src/CodegenSchema.js | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 2b26e7c0844814..6ed318c6237ba1 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -263,6 +263,8 @@ export type SchemaType = $ReadOnly<{| * This is necessary for us to start unifying the notion of a "type * annotation" across the codegen schema as a whole. */ +export type Required = $ReadOnly<{...T, nullable: false}>; + export type NativeModuleSchema = $ReadOnly<{| // We only support aliases to Objects aliases: $ReadOnly, @@ -270,11 +272,7 @@ export type NativeModuleSchema = $ReadOnly<{| |}>; export type NativeModuleAliasMap = { - [aliasName: string]: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - nullable: false, - |}>, + [aliasName: string]: Required, }; export type NativeModulePropertySchema = $ReadOnly<{| @@ -298,16 +296,16 @@ export type NativeModuleMethodParamSchema = $ReadOnly<{| export type NativeModuleObjectTypeAnnotation = $ReadOnly<{| type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, + properties: $ReadOnlyArray< + $ReadOnly<{| + name: string, + optional: boolean, + typeAnnotation: NativeModuleBaseTypeAnnotation, + |}>, + >, nullable: boolean, |}>; -export type NativeModuleObjectTypeAnnotationPropertySchema = $ReadOnly<{| - optional: boolean, - name: string, - typeAnnotation: NativeModuleBaseTypeAnnotation, -|}>; - export type NativeModuleArrayTypeAnnotation = $ReadOnly<{| type: 'ArrayTypeAnnotation', /** From 92a6722bf279b6cff1fa0b69bd0ba7d85ed3518a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 20/52] Refactor: Make NativeModuleAliasMap $ReadOnly Summary: We were using `$ReadOnly` everywhere, so I figured we'd just make the type itself `$ReadOnly`. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23645207 fbshipit-source-id: 4e018d5768f4fcfd00492def7d840a5054cb2b73 --- packages/react-native-codegen/src/CodegenSchema.js | 6 +++--- .../src/parsers/flow/modules/index.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 6ed318c6237ba1..55d9b2aa7b7f94 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -267,13 +267,13 @@ export type Required = $ReadOnly<{...T, nullable: false}>; export type NativeModuleSchema = $ReadOnly<{| // We only support aliases to Objects - aliases: $ReadOnly, + aliases: NativeModuleAliasMap, properties: $ReadOnlyArray, |}>; -export type NativeModuleAliasMap = { +export type NativeModuleAliasMap = $ReadOnly<{| [aliasName: string]: Required, -}; +|}>; export type NativeModulePropertySchema = $ReadOnly<{| name: string, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 31de4e511f8e85..ca1b95216e2fe1 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -38,7 +38,7 @@ function translateTypeAnnotation( */ flowTypeAnnotation: $FlowFixMe, types: TypeDeclarationMap, - aliasMap: NativeModuleAliasMap, + aliasMap: {...NativeModuleAliasMap}, ): NativeModuleTypeAnnotation { const { nullable, @@ -306,7 +306,7 @@ function translateFunctionTypeAnnotation( flowFunctionTypeAnnotation: $FlowFixMe, types: TypeDeclarationMap, nullable: boolean, - aliasMap: NativeModuleAliasMap, + aliasMap: {...NativeModuleAliasMap}, ): NativeModuleFunctionTypeAnnotation { const params: Array = []; for (const flowParam of (flowFunctionTypeAnnotation.params: $ReadOnlyArray<$FlowFixMe>)) { @@ -367,7 +367,7 @@ function buildPropertySchema( // Flow type this node property: $FlowFixMe, types: TypeDeclarationMap, - aliasMap: NativeModuleAliasMap, + aliasMap: {...NativeModuleAliasMap}, ): NativeModulePropertySchema { let nullable = false; let {key, value} = property; @@ -422,7 +422,7 @@ function buildModuleSchema( return (declaration.body.properties: $ReadOnlyArray<$FlowFixMe>) .filter(property => property.type === 'ObjectTypeProperty') .map(property => { - const aliasMap: NativeModuleAliasMap = {}; + const aliasMap: {...NativeModuleAliasMap} = {}; return { aliasMap: aliasMap, propertySchema: buildPropertySchema( From 4927de6011026831295df2776c35645364c25527 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 21/52] Rename GenericPromiseTypeAnnotation to PromiseTypeAnnotation Summary: We have first class support for Promises in our codegen. So, it's more appropriate to just call this PromiseTypeAnnotation, as opposed to GenericPromiseTypeAnnotation. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23645209 fbshipit-source-id: bfc0b909750e221e18be33acf197f342a2918aa9 --- .../codegen/generator/model/PromiseType.java | 2 +- .../react-native-codegen/src/CodegenSchema.js | 2 +- .../src/generators/modules/GenerateModuleH.js | 2 +- .../generators/modules/GenerateModuleHObjCpp.js | 5 ++--- .../generators/modules/GenerateModuleJavaSpec.js | 4 ++-- .../generators/modules/GenerateModuleJniCpp.js | 15 ++++++--------- .../src/generators/modules/GenerateModuleMm.js | 6 +++--- .../modules/__test_fixtures__/fixtures.js | 8 ++++---- .../module-parser-snapshot-test.js.snap | 6 +++--- .../modules/__tests__/module-parser-e2e-test.js | 4 +--- .../src/parsers/flow/modules/index.js | 6 +++--- 11 files changed, 27 insertions(+), 33 deletions(-) diff --git a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/model/PromiseType.java b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/model/PromiseType.java index b4051ac81d7f61..c243cae7d73a1e 100644 --- a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/model/PromiseType.java +++ b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/src/main/java/com/facebook/react/codegen/generator/model/PromiseType.java @@ -8,7 +8,7 @@ package com.facebook.react.codegen.generator.model; public final class PromiseType extends Type { - public static final String TYPE_NAME = "GenericPromiseTypeAnnotation"; + public static final String TYPE_NAME = "PromiseTypeAnnotation"; public PromiseType(final TypeId typeId) { super(typeId); diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 55d9b2aa7b7f94..a2b3d54d5edc95 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -364,7 +364,7 @@ export type NativeModuleTypeAliasTypeAnnotation = $ReadOnly<{| |}>; export type NativeModulePromiseTypeAnnotation = $ReadOnly<{| - type: 'GenericPromiseTypeAnnotation', + type: 'PromiseTypeAnnotation', nullable: boolean, |}>; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index 7342ad01a7c32a..f2aaa32f41f133 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -92,7 +92,7 @@ function translatePrimitiveJSTypeToCpp( return 'jsi::Array'; case 'FunctionTypeAnnotation': return 'jsi::Function'; - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'jsi::Value'; default: // TODO (T65847278): Figure out why this does not work. diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js index c9f173df868e37..cd54439ff917f4 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js @@ -44,8 +44,7 @@ const protocolTemplate = `::_STRUCTS_:: `; const callbackArgs = prop => - prop.typeAnnotation.returnTypeAnnotation.type === - 'GenericPromiseTypeAnnotation' + prop.typeAnnotation.returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? `${ prop.typeAnnotation.params.length === 0 ? '' : '\n resolve' }:(RCTPromiseResolveBlock)resolve @@ -171,7 +170,7 @@ function translatePrimitiveJSTypeToObjCTypeForReturn( throw new Error(createErrorMessage(typeAnnotation.name)); } case 'VoidTypeAnnotation': - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'void'; case 'StringTypeAnnotation': return wrapIntoNullableIfNeeded('NSString *'); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 43937022e4f52c..45ff4ba8dcfac7 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -130,7 +130,7 @@ function translateFunctionReturnTypeToJavaType( throw new Error(createErrorMessage(returnTypeAnnotation.name)); } case 'VoidTypeAnnotation': - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'void'; case 'StringTypeAnnotation': return wrapIntoNullableIfNeeded('String'); @@ -279,7 +279,7 @@ module.exports = { ); const returningPromise = method.typeAnnotation.returnTypeAnnotation.type === - 'GenericPromiseTypeAnnotation'; + 'PromiseTypeAnnotation'; const isSyncMethod = method.typeAnnotation.returnTypeAnnotation.type !== 'VoidTypeAnnotation' && !returningPromise; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js index aac88138b51f45..a97083d86bd7f3 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js @@ -99,7 +99,7 @@ function translateReturnTypeToKind( case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': return 'NumberKind'; - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'PromiseKind'; case 'GenericObjectTypeAnnotation': case 'ObjectTypeAnnotation': @@ -148,7 +148,7 @@ function translateParamTypeToJniType( case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': return nullable ? 'Ljava/lang/Double;' : 'D'; - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'Lcom/facebook/react/bridge/Promise;'; case 'GenericObjectTypeAnnotation': case 'ObjectTypeAnnotation': @@ -191,7 +191,7 @@ function translateReturnTypeToJniType( case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': return nullable ? 'Ljava/lang/Double;' : 'D'; - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'Lcom/facebook/react/bridge/Promise;'; case 'GenericObjectTypeAnnotation': case 'ObjectTypeAnnotation': @@ -214,8 +214,7 @@ function translateMethodTypeToJniSignature( const params = [...typeAnnotation.params]; let processedReturnTypeAnnotation = returnTypeAnnotation; - const isPromiseReturn = - returnTypeAnnotation.type === 'GenericPromiseTypeAnnotation'; + const isPromiseReturn = returnTypeAnnotation.type === 'PromiseTypeAnnotation'; if (isPromiseReturn) { processedReturnTypeAnnotation = { nullable: false, @@ -247,13 +246,11 @@ function translateMethodForImplementation( const numberOfParams = property.typeAnnotation.params.length + - (returnTypeAnnotation.type === 'GenericPromiseTypeAnnotation' ? 1 : 0); + (returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? 1 : 0); const translatedArguments = property.typeAnnotation.params .map(param => param.name) .concat( - returnTypeAnnotation.type === 'GenericPromiseTypeAnnotation' - ? ['promise'] - : [], + returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? ['promise'] : [], ) .slice(1) .join(':') diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js index 8b60d07e127429..53a0585886e3dd 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js @@ -96,7 +96,7 @@ function translateReturnTypeToKind(typeAnnotation): string { case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': return 'NumberKind'; - case 'GenericPromiseTypeAnnotation': + case 'PromiseTypeAnnotation': return 'PromiseKind'; case 'GenericObjectTypeAnnotation': case 'ObjectTypeAnnotation': @@ -117,11 +117,11 @@ function translateMethodForImplementation(property): string { const numberOfParams = property.typeAnnotation.params.length + - (returnTypeAnnotation.type === 'GenericPromiseTypeAnnotation' ? 2 : 0); + (returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? 2 : 0); const translatedArguments = property.typeAnnotation.params .map(param => param.name) .concat( - returnTypeAnnotation.type === 'GenericPromiseTypeAnnotation' + returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? ['resolve', 'reject'] : [], ) diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index 1c5a3b9127da42..4f4f5fc14bd92d 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -278,7 +278,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { nullable: false, - type: 'GenericPromiseTypeAnnotation', + type: 'PromiseTypeAnnotation', }, params: [ { @@ -1132,7 +1132,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { - type: 'GenericPromiseTypeAnnotation', + type: 'PromiseTypeAnnotation', nullable: false, }, params: [ @@ -1154,7 +1154,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { - type: 'GenericPromiseTypeAnnotation', + type: 'PromiseTypeAnnotation', nullable: false, }, params: [ @@ -1182,7 +1182,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { - type: 'GenericPromiseTypeAnnotation', + type: 'PromiseTypeAnnotation', nullable: false, }, params: [ diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 96cbea8e38d1e2..6c35735fee2055 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -1248,7 +1248,7 @@ Object { "params": Array [], "returnTypeAnnotation": Object { "nullable": false, - "type": "GenericPromiseTypeAnnotation", + "type": "PromiseTypeAnnotation", }, "type": "FunctionTypeAnnotation", }, @@ -1261,7 +1261,7 @@ Object { "params": Array [], "returnTypeAnnotation": Object { "nullable": false, - "type": "GenericPromiseTypeAnnotation", + "type": "PromiseTypeAnnotation", }, "type": "FunctionTypeAnnotation", }, @@ -1274,7 +1274,7 @@ Object { "params": Array [], "returnTypeAnnotation": Object { "nullable": false, - "type": "GenericPromiseTypeAnnotation", + "type": "PromiseTypeAnnotation", }, "type": "FunctionTypeAnnotation", }, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js index e4647258fe32e3..b48f155accf153 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/module-parser-e2e-test.js @@ -708,9 +708,7 @@ describe('Flow Module Parser', () => { promiseFlowType => { it(`should parse methods that have ${RETURN_TYPE_DESCRIPTION} return of type '${promiseFlowType}'`, () => { const [returnTypeAnnotation] = parseReturnType(promiseFlowType); - expect(returnTypeAnnotation.type).toBe( - 'GenericPromiseTypeAnnotation', - ); + expect(returnTypeAnnotation.type).toBe('PromiseTypeAnnotation'); }); }, ); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index ca1b95216e2fe1..a1da76184fba9c 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -62,7 +62,7 @@ function translateTypeAnnotation( ); return { nullable, - type: 'GenericPromiseTypeAnnotation', + type: 'PromiseTypeAnnotation', }; } case 'Array': @@ -90,7 +90,7 @@ function translateTypeAnnotation( `${typeAnnotation.id.name} element type cannot be 'void'.`, ); invariant( - elementType.type !== 'GenericPromiseTypeAnnotation', + elementType.type !== 'PromiseTypeAnnotation', `${typeAnnotation.id.name} element type cannot be 'Promise'.`, ); @@ -328,7 +328,7 @@ function translateFunctionTypeAnnotation( ); invariant( - paramTypeAnnotation.type !== 'GenericPromiseTypeAnnotation', + paramTypeAnnotation.type !== 'PromiseTypeAnnotation', `Parameter ${paramName} cannot have type 'Promise'.`, ); From 91a7da087b6ee6cbe2815a9cdcdf7864daa7f72f Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 22/52] Refactor: Make NativeModuleArrayTypeAnnotation elementType customizable Summary: In the future, we'll use `NativeModuleArrayTypeAnnotation` inside JS struct objects. Structs cannot contain `ObjectTypeAnnotations` anywhere. Therefore, we need the elementType of `NativeModuuleArrayTypeAnnotation`'s elementType customizable. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23645210 fbshipit-source-id: 97abb993d59536ebd68ec08b18ce7f2801c68a2d --- packages/react-native-codegen/src/CodegenSchema.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index a2b3d54d5edc95..7e35b52207aac7 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -306,13 +306,15 @@ export type NativeModuleObjectTypeAnnotation = $ReadOnly<{| nullable: boolean, |}>; -export type NativeModuleArrayTypeAnnotation = $ReadOnly<{| +export type NativeModuleArrayTypeAnnotation< + T = NativeModuleBaseTypeAnnotation, +> = $ReadOnly<{| type: 'ArrayTypeAnnotation', /** * TODO(T72031674): Migrate all our NativeModule specs to not use * invalid Array ElementTypes. Then, make the elementType required. */ - elementType?: NativeModuleBaseTypeAnnotation, + elementType?: T, nullable: boolean, |}>; @@ -383,7 +385,7 @@ export type NativeModuleBaseTypeAnnotation = | NativeModuleGenericObjectTypeAnnotation | NativeModuleReservedFunctionValueTypeAnnotation | NativeModuleTypeAliasTypeAnnotation - | NativeModuleArrayTypeAnnotation + | NativeModuleArrayTypeAnnotation<> | NativeModuleObjectTypeAnnotation; export type NativeModuleParamTypeAnnotation = From 5f5ccfcb2cd177babce086e57b5ac8e5442e3571 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 23/52] Update generator fixtures to comply with Schema flow types Summary: In diffs below, we made several changes to the NativeModule schema. This diff just ensures that the input to our generator snapshot tests, which are module schemas, are valid. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D23633942 fbshipit-source-id: 444ccd60f6ec76e348a8e54b946260464ff3aeee --- .../modules/__test_fixtures__/fixtures.js | 240 +++++++++++++++--- 1 file changed, 202 insertions(+), 38 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index 4f4f5fc14bd92d..92a7dc3489823e 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -46,6 +46,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { name: 'const1', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -53,6 +54,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { name: 'const2', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -60,6 +62,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { name: 'const3', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], @@ -92,10 +95,11 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'arg', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, ], @@ -113,10 +117,11 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'arg', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -134,10 +139,11 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'arg', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], @@ -153,17 +159,20 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { nullable: false, type: 'ArrayTypeAnnotation', elementType: { - type: 'AnyTypeAnnotation', + type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, params: [ { name: 'arg', - nullable: false, + optional: false, typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { - type: 'AnyTypeAnnotation', + type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, }, @@ -182,10 +191,11 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'arg', typeAnnotation: { type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, ], @@ -204,11 +214,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'arg', typeAnnotation: { type: 'ReservedFunctionValueTypeAnnotation', name: 'RootTag', + nullable: false, }, }, ], @@ -226,24 +237,27 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'x', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { - nullable: false, + optional: false, name: 'y', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { - nullable: false, + optional: false, name: 'z', typeAnnotation: { type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, ], @@ -262,9 +276,15 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { params: [ { name: 'callback', - nullable: false, + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', + params: [], + returnTypeAnnotation: { + type: 'VoidTypeAnnotation', + nullable: false, + }, + nullable: false, }, }, ], @@ -282,10 +302,11 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'error', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, ], @@ -428,6 +449,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'D', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -435,6 +457,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'E', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -442,22 +465,25 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'F', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], }, params: [ { - nullable: false, + optional: false, name: 'A', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'D', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -465,12 +491,14 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'E', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'D', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -478,6 +506,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'E', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -485,6 +514,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'F', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -492,6 +522,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'id', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -502,6 +533,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'F', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], @@ -522,16 +554,18 @@ const COMPLEX_OBJECTS: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'A', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: true, name: 'optionalNumberProperty', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -539,8 +573,10 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'optionalArrayProperty', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'NumberTypeAnnotation', + nullable: false, }, }, }, @@ -549,12 +585,14 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'optionalObjectProperty', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'x', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -562,6 +600,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'y', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -572,6 +611,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'optionalGenericObjectProperty', typeAnnotation: { type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, { @@ -579,6 +619,7 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'optionalBooleanTypeProperty', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, ], @@ -599,37 +640,51 @@ const COMPLEX_OBJECTS: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'options', typeAnnotation: { type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, { name: 'callback', - nullable: false, + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', + params: [], + returnTypeAnnotation: { + type: 'VoidTypeAnnotation', + nullable: false, + }, + nullable: false, }, }, { name: 'extras', - nullable: true, + optional: true, typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'key', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { optional: false, name: 'value', + typeAnnotation: { + type: 'GenericObjectTypeAnnotation', + nullable: false, + }, }, ], }, @@ -650,18 +705,21 @@ const COMPLEX_OBJECTS: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'options', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'arrayOfNumbers', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'NumberTypeAnnotation', + nullable: false, }, }, }, @@ -670,8 +728,10 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'optionalArrayOfNumbers', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'NumberTypeAnnotation', + nullable: false, }, }, }, @@ -680,8 +740,10 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'arrayOfStrings', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'StringTypeAnnotation', + nullable: false, }, }, }, @@ -690,8 +752,10 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'optionalArrayOfStrings', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'StringTypeAnnotation', + nullable: false, }, }, }, @@ -700,14 +764,17 @@ const COMPLEX_OBJECTS: SchemaType = { name: 'arrayOfObjects', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'numberProperty', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -735,18 +802,22 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { AliasTurboModule: { aliases: { Options: { + type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'offset', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'x', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -754,6 +825,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'y', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -764,12 +836,14 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'size', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'width', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -777,6 +851,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'height', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -787,12 +862,14 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'displaySize', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'width', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -800,6 +877,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'height', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -810,6 +888,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'resizeMode', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -817,10 +896,10 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { name: 'allowExternalStorage', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, ], - type: 'ObjectTypeAnnotation', }, }, properties: [ @@ -849,11 +928,12 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'cropData', typeAnnotation: { type: 'TypeAliasTypeAnnotation', name: 'Options', + nullable: false, }, }, ], @@ -875,12 +955,14 @@ const REAL_MODULE_EXAMPLE: SchemaType = { aliases: { PhotoIdentifierImage: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'uri', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -888,6 +970,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'playableDuration', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -895,6 +978,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'width', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -902,6 +986,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'height', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -909,6 +994,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'isStored', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -916,18 +1002,21 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'filename', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], }, PhotoIdentifier: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'node', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, @@ -935,6 +1024,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { typeAnnotation: { type: 'TypeAliasTypeAnnotation', name: 'PhotoIdentifierImage', + nullable: false, }, }, { @@ -942,6 +1032,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'type', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -949,6 +1040,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'group_name', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -956,6 +1048,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'timestamp', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -963,12 +1056,14 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'location', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'longitude', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -976,6 +1071,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'latitude', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -983,6 +1079,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'altitude', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -990,6 +1087,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'heading', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -997,6 +1095,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'speed', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -1009,15 +1108,18 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, PhotoIdentifiersPage: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'edges', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'TypeAliasTypeAnnotation', name: 'PhotoIdentifier', + nullable: false, }, }, }, @@ -1026,12 +1128,14 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'page_info', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'has_next_page', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -1039,6 +1143,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'start_cursor', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1046,6 +1151,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'end_cursor', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], @@ -1055,12 +1161,14 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, GetPhotosParams: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'first', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -1068,6 +1176,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'after', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1075,6 +1184,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'groupName', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1082,6 +1192,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'groupTypes', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1089,6 +1200,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'assetType', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1096,6 +1208,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'maxSize', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -1103,8 +1216,10 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'mimeTypes', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'StringTypeAnnotation', + nullable: false, }, }, }, @@ -1137,11 +1252,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'params', typeAnnotation: { type: 'TypeAliasTypeAnnotation', name: 'GetPhotosParams', + nullable: false, }, }, ], @@ -1159,17 +1275,19 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'uri', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { - nullable: false, + optional: false, name: 'type', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, ], @@ -1188,11 +1306,13 @@ const REAL_MODULE_EXAMPLE: SchemaType = { params: [ { name: 'assets', - nullable: false, + optional: false, typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'StringTypeAnnotation', + nullable: false, }, }, }, @@ -1220,16 +1340,18 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'config', typeAnnotation: { type: 'ObjectTypeAnnotation', + nullable: false, properties: [ { optional: false, name: 'unmirrorFrontFacingCamera', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -1237,6 +1359,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'videoMode', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, ], @@ -1244,16 +1367,28 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, { name: 'successCallback', - nullable: false, + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', + params: [], + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + nullable: false, }, }, { name: 'cancelCallback', - nullable: false, + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', + params: [], + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + nullable: false, }, }, ], @@ -1275,6 +1410,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'column', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -1282,6 +1418,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'file', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1289,6 +1426,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'lineNumber', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -1296,6 +1434,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'methodName', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1303,10 +1442,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'collapse', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, ], type: 'ObjectTypeAnnotation', + nullable: false, }, ExceptionData: { properties: [ @@ -1315,6 +1456,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'message', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1322,6 +1464,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'originalMessage', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1329,6 +1472,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'name', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1336,6 +1480,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'componentStack', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { @@ -1343,9 +1488,11 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'stack', typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'TypeAliasTypeAnnotation', name: 'StackFrame', + nullable: false, }, }, }, @@ -1354,6 +1501,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'id', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, { @@ -1361,6 +1509,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'isFatal', typeAnnotation: { type: 'BooleanTypeAnnotation', + nullable: false, }, }, { @@ -1368,10 +1517,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { name: 'extraData', typeAnnotation: { type: 'GenericObjectTypeAnnotation', + nullable: false, }, }, ], type: 'ObjectTypeAnnotation', + nullable: false, }, }, properties: [ @@ -1386,28 +1537,32 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'message', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { name: 'stack', - nullable: false, + optional: false, typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'TypeAliasTypeAnnotation', name: 'StackFrame', + nullable: false, }, }, }, { - nullable: false, + optional: false, name: 'exceptionId', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -1425,28 +1580,32 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'message', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { name: 'stack', - nullable: false, + optional: false, typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'TypeAliasTypeAnnotation', name: 'StackFrame', + nullable: false, }, }, }, { - nullable: false, + optional: false, name: 'exceptionId', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], @@ -1464,11 +1623,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'data', typeAnnotation: { type: 'TypeAliasTypeAnnotation', name: 'ExceptionData', + nullable: false, }, }, ], @@ -1486,28 +1646,32 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, params: [ { - nullable: false, + optional: false, name: 'message', typeAnnotation: { type: 'StringTypeAnnotation', + nullable: false, }, }, { name: 'stack', - nullable: false, + optional: false, typeAnnotation: { type: 'ArrayTypeAnnotation', + nullable: false, elementType: { type: 'TypeAliasTypeAnnotation', name: 'StackFrame', + nullable: false, }, }, }, { - nullable: false, + optional: false, name: 'exceptionId', typeAnnotation: { type: 'NumberTypeAnnotation', + nullable: false, }, }, ], From c3001938537b7f5590d71e536653ebfd083ffa52 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 24/52] Create utilities for module generators Summary: There are two operations we do in every NativeModule generator: - We convert the `SchemaType` into a map of NativeModule schemas - If the type-annotation is a TypeAliasTypeAnnotation, we resolve it by doing a lookup on the NativeModuleAliasMap. This is usually followed by an invariant to assert that the lookup didn't fail. Both procedures have been translated into utilities for use across our generators. I also deleted `getTypeAliasTypeAnnotation` which will no longer be used. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23667249 fbshipit-source-id: 4e34078980e2caa4daed77c38b1168bfc161c31c --- .../src/generators/modules/Utils.js | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/Utils.js b/packages/react-native-codegen/src/generators/modules/Utils.js index 8ce5c95416f610..6985b861c7989e 100644 --- a/packages/react-native-codegen/src/generators/modules/Utils.js +++ b/packages/react-native-codegen/src/generators/modules/Utils.js @@ -10,35 +10,43 @@ 'use strict'; -import type {ObjectTypeAliasTypeShape} from '../../CodegenSchema'; +import type { + SchemaType, + NativeModuleAliasMap, + Required, + NativeModuleObjectTypeAnnotation, + NativeModuleSchema, +} from '../../CodegenSchema'; -function getTypeAliasTypeAnnotation( - name: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): $ReadOnly { - const typeAnnotation = aliases[name]; - if (!typeAnnotation) { - throw Error(`No type annotation found for "${name}" in schema`); - } - if (typeAnnotation.type === 'ObjectTypeAnnotation') { - if (typeAnnotation.properties) { - return typeAnnotation; - } +const invariant = require('invariant'); - throw new Error( - `Unsupported type for "${name}". Please provide properties.`, - ); - } - // $FlowFixMe[incompatible-type] - if (typeAnnotation.type === 'TypeAliasTypeAnnotation') { - return getTypeAliasTypeAnnotation(typeAnnotation.name, aliases); - } +export type AliasResolver = ( + aliasName: string, +) => Required; + +function createAliasResolver(aliasMap: NativeModuleAliasMap): AliasResolver { + return (aliasName: string) => { + const alias = aliasMap[aliasName]; + invariant(alias != null, `Unable to resolve type alias '${aliasName}'.`); + return alias; + }; +} - throw Error( - `Unsupported type annotation in alias "${name}", found: ${typeAnnotation.type}`, - ); +function getModules( + schema: SchemaType, +): $ReadOnly<{|[moduleName: string]: NativeModuleSchema|}> { + return Object.keys(schema.modules) + .map( + moduleName => schema.modules[moduleName].nativeModules, + ) + .filter(Boolean) + .reduce<{+[string]: NativeModuleSchema}>( + (acc, modules) => ({...acc, ...modules}), + {}, + ); } module.exports = { - getTypeAliasTypeAnnotation, + createAliasResolver, + getModules, }; From c267b8de7291a0aef67f6fb24d78dbc85385c120 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 25/52] Rewrite ObjC++ module generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: ## Misc. Improvements * We now have 95%+ flow coverage in all generator files. Henceforth, we can make changes to these files with more confidence, and trust flow to catch more errors. This should also improve the DevX of working on these files. * Better templates: Instead of doing string replace with RegExps, we instead use functions and leverage JS template literals to generate our code. A few benefits: (1) data dependencies of templates are clearly visible, and statically checked by flow, (2) the templates are more readable in VSCode. * Merged the GenerateModuleHObjCpp.js and GenerateModuleMm.js generators. They can share a lot of logic, so it's not a good idea to keep them separate. * The ObjC++ module generator no longer generates “dead” structs (i.e structs that aren’t used by type-safety infra). In fact, it explicitly only supports the types in our Wiki. (I know this wasn’t the case with the legacy codegen, because we were generating native code for enums in the legacy codegen). This is a mixed bag. The test to verify correctness will be more difficult to write. However, keeping structs in the codegen needlessly complicates the parsers + generators, and creates technical debt for us to clean up later. ## Abstractions - **StructCollector:** As we serialize NativeModule methods, when we detect an ObjectTypeAnnotation in the return type of `getConstants()` or inside a method param, we must create a Struct JS object for it. When we detect a type-alias (also in the same locations), we must look up that type-alias and create a Struct from its RHS. A Struct is basically an ObjectTypeAnnotation with a context (i.e: used in getConstants() vs as a method param), that cannot contain other ObjectTypeAnnotations. - **serializeMethod.js** Given a NativeModule method type annotation, output the protocol method, JS return type, selector, a record of which params were structs, and which structs. Basically, this is all the information necessary to generate the declaration and implementation codegen for a partiular NativeModule method. - **serializeStruct/*.js**: After creating all these Structs, we need to loop over all of them, and tranform them into ObjC++ code. - **serializeStruct.js**: Depending on the struct context, calls either `serializeRegularStruct.js` or `serializeConstantsStruct.js`. Both of these files have the same layout/abstractions. They look very similar. - **serializeModule.js:** Outputs RCTCxxConvert categories for transforming `NSDictionary *` into C++ structs. Outputs ObjCTurboModule subclass. ## Algorithm ``` for spec in NativeModuleSpecs structCollector = new StructCollector resolveAlias = (aliasName) => nullthrows(spec.aliases[aliasName]) methodDatas = [] for method in methods(spec) methodData.push(serializeMethod(method, structCollector, resolveAlias)) end structs = structCollector.getStructs() output generateImplCodegen(methodDatas, structs) output generateHeaderCodegen(methodDatas, structs) end ``` Changelog: [Internal] Reviewed By: hramos Differential Revision: D23633940 fbshipit-source-id: 7c29f458b65434f4865ef1993061b0f0dc7d04ce --- Libraries/TypeSafety/RCTConvertHelpers.h | 1 + Libraries/TypeSafety/RCTConvertHelpers.mm | 6 + packages/react-native-codegen/.babelrc | 1 + packages/react-native-codegen/package.json | 1 + .../src/generators/RNCodegen.js | 6 +- .../modules/GenerateModuleHObjCpp.js | 414 ------- .../generators/modules/GenerateModuleMm.js | 320 ------ .../GenerateModuleObjCpp/StructCollector.js | 191 ++++ .../modules/GenerateModuleObjCpp/Utils.js | 36 + .../header/serializeConstantsStruct.js | 263 +++++ .../header/serializeRegularStruct.js | 251 ++++ .../header/serializeStruct.js | 35 + .../modules/GenerateModuleObjCpp/index.js | 210 ++++ .../GenerateModuleObjCpp/serializeMethod.js | 413 +++++++ .../source/serializeModule.js | 125 ++ .../modules/ObjCppUtils/GenerateStructs.js | 452 -------- .../GenerateStructsForConstants.js | 275 ----- .../generators/modules/ObjCppUtils/Utils.js | 112 -- .../__test_fixtures__/structFixtures.js | 218 ---- .../__tests__/GenerateModuleHObjCpp-test.js | 5 +- .../__tests__/GenerateModuleMm-test.js | 7 +- .../modules/__tests__/GenerateStructs-test.js | 31 - .../GenerateModuleHObjCpp-test.js.snap | 1011 ++++++----------- .../GenerateModuleMm-test.js.snap | 584 ++++++---- .../GenerateStructs-test.js.snap | 284 ----- 25 files changed, 2236 insertions(+), 3016 deletions(-) delete mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js delete mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js delete mode 100644 packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js delete mode 100644 packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js delete mode 100644 packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js delete mode 100644 packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js delete mode 100644 packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js delete mode 100644 packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap diff --git a/Libraries/TypeSafety/RCTConvertHelpers.h b/Libraries/TypeSafety/RCTConvertHelpers.h index 1b6bf9341e7a86..0b7144b9c8ea2d 100644 --- a/Libraries/TypeSafety/RCTConvertHelpers.h +++ b/Libraries/TypeSafety/RCTConvertHelpers.h @@ -49,6 +49,7 @@ NSArray *RCTConvertOptionalVecToArray(const folly::Optional &vec) bool RCTBridgingToBool(id value); folly::Optional RCTBridgingToOptionalBool(id value); NSString *RCTBridgingToString(id value); +NSString *RCTBridgingToOptionalString(id value); folly::Optional RCTBridgingToOptionalDouble(id value); double RCTBridgingToDouble(id value); NSArray *RCTBridgingToArray(id value); diff --git a/Libraries/TypeSafety/RCTConvertHelpers.mm b/Libraries/TypeSafety/RCTConvertHelpers.mm index 69fb3e4a3de4f4..cd79c41f6fece4 100644 --- a/Libraries/TypeSafety/RCTConvertHelpers.mm +++ b/Libraries/TypeSafety/RCTConvertHelpers.mm @@ -27,6 +27,12 @@ bool RCTBridgingToBool(id value) return [RCTConvert NSString:RCTNilIfNull(value)]; } +NSString *RCTBridgingToOptionalString(id value) +{ + return RCTBridgingToString(value); +} + + folly::Optional RCTBridgingToOptionalDouble(id value) { if (!RCTNilIfNull(value)) { diff --git a/packages/react-native-codegen/.babelrc b/packages/react-native-codegen/.babelrc index b8ac81899b77e0..7a6194fbaa55d8 100644 --- a/packages/react-native-codegen/.babelrc +++ b/packages/react-native-codegen/.babelrc @@ -5,6 +5,7 @@ "@babel/plugin-transform-destructuring", "@babel/plugin-transform-flow-strip-types", "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-nullish-coalescing-operator", "@babel/plugin-proposal-optional-chaining" ] diff --git a/packages/react-native-codegen/package.json b/packages/react-native-codegen/package.json index 6f6cac7bb3599f..014bd03565390b 100644 --- a/packages/react-native-codegen/package.json +++ b/packages/react-native-codegen/package.json @@ -24,6 +24,7 @@ }, "devDependencies": { "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", "@babel/plugin-proposal-optional-chaining": "^7.0.0", diff --git a/packages/react-native-codegen/src/generators/RNCodegen.js b/packages/react-native-codegen/src/generators/RNCodegen.js index 576d984abd8d71..b6f6e02a922255 100644 --- a/packages/react-native-codegen/src/generators/RNCodegen.js +++ b/packages/react-native-codegen/src/generators/RNCodegen.js @@ -25,11 +25,10 @@ const generatePropsCpp = require('./components/GeneratePropsCpp.js'); const generatePropsH = require('./components/GeneratePropsH.js'); const generateModuleH = require('./modules/GenerateModuleH.js'); const generateModuleCpp = require('./modules/GenerateModuleCpp.js'); -const generateModuleHObjCpp = require('./modules/GenerateModuleHObjCpp.js'); +const generateModuleObjCpp = require('./modules/GenerateModuleObjCpp'); const generateModuleJavaSpec = require('./modules/GenerateModuleJavaSpec.js'); const GenerateModuleJniCpp = require('./modules/GenerateModuleJniCpp.js'); const GenerateModuleJniH = require('./modules/GenerateModuleJniH.js'); -const generateModuleMm = require('./modules/GenerateModuleMm.js'); const generatePropsJavaInterface = require('./components/GeneratePropsJavaInterface.js'); const generatePropsJavaDelegate = require('./components/GeneratePropsJavaDelegate.js'); const generateTests = require('./components/GenerateTests.js'); @@ -74,8 +73,7 @@ const GENERATORS = { modules: [ generateModuleCpp.generate, generateModuleH.generate, - generateModuleHObjCpp.generate, - generateModuleMm.generate, + generateModuleObjCpp.generate, ], // TODO: Refactor this to consolidate various C++ output variation instead of forking Android. modulesAndroid: [ diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js deleted file mode 100644 index cd54439ff917f4..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js +++ /dev/null @@ -1,414 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict - * @format - */ - -'use strict'; - -import type { - SchemaType, - FunctionTypeAnnotationParam, - FunctionTypeAnnotationReturn, - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../CodegenSchema'; - -const { - translateObjectsForStructs, - capitalizeFirstLetter, - getNamespacedStructName, -} = require('./ObjCppUtils/GenerateStructs'); - -const {getTypeAliasTypeAnnotation} = require('./Utils'); - -type FilesOutput = Map; - -const moduleTemplate = ` /** - * ObjC++ class for module '::_MODULE_NAME_::' - */ - class JSI_EXPORT Native::_MODULE_NAME_::SpecJSI : public ObjCTurboModule { - public: - Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms); - };`; - -const protocolTemplate = `::_STRUCTS_:: - -@protocol Native::_MODULE_NAME_::Spec -::_MODULE_PROPERTIES_:: -@end -`; - -const callbackArgs = prop => - prop.typeAnnotation.returnTypeAnnotation.type === 'PromiseTypeAnnotation' - ? `${ - prop.typeAnnotation.params.length === 0 ? '' : '\n resolve' - }:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject` - : ''; - -const template = ` -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * ${'@'}generated by codegen project: GenerateModuleHObjCpp.js - */ - -#ifndef __cplusplus -#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. -#endif - -#import - -#import - -#import - -#import -#import -#import - -#import -#import -#import - -#import - -::_PROTOCOLS_:: - -namespace facebook { - namespace react { -::_MODULES_:: - } // namespace react -} // namespace facebook -`; - -type ObjectForGeneratingStructs = $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, -|}>; - -const constants = `- (facebook::react::ModuleConstants)constantsToExport; -- (facebook::react::ModuleConstants)getConstants;`; - -function translatePrimitiveJSTypeToObjCType( - param: FunctionTypeAnnotationParam, - createErrorMessage: (typeName: string) => string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -) { - const {nullable, typeAnnotation} = param; - - function wrapIntoNullableIfNeeded(generatedType: string) { - return nullable ? `${generatedType} _Nullable` : generatedType; - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return nullable ? 'NSNumber *' : 'double'; - default: - (realTypeAnnotation.name: empty); - throw new Error(createErrorMessage(realTypeAnnotation.name)); - } - case 'StringTypeAnnotation': - return wrapIntoNullableIfNeeded('NSString *'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return nullable ? 'NSNumber *' : 'double'; - case 'BooleanTypeAnnotation': - return nullable ? 'NSNumber * _Nullable' : 'BOOL'; - case 'ObjectTypeAnnotation': - if (typeAnnotation.type === 'TypeAliasTypeAnnotation') { - return getNamespacedStructName(typeAnnotation.name) + ' &'; - } - return wrapIntoNullableIfNeeded('NSDictionary *'); - case 'GenericObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); - case 'ArrayTypeAnnotation': - return wrapIntoNullableIfNeeded('NSArray *'); - case 'FunctionTypeAnnotation': - return 'RCTResponseSenderBlock'; - default: - // TODO (T65847278): Figure out why this does not work. - // (type: empty); - throw new Error(createErrorMessage(realTypeAnnotation.type)); - } -} - -function translatePrimitiveJSTypeToObjCTypeForReturn( - typeAnnotation: FunctionTypeAnnotationReturn, - createErrorMessage: (typeName: string) => string, -) { - function wrapIntoNullableIfNeeded(generatedType: string) { - return typeAnnotation.nullable - ? `${generatedType} _Nullable` - : generatedType; - } - switch (typeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { - case 'RootTag': - return wrapIntoNullableIfNeeded('NSNumber *'); - default: - (typeAnnotation.name: empty); - throw new Error(createErrorMessage(typeAnnotation.name)); - } - case 'VoidTypeAnnotation': - case 'PromiseTypeAnnotation': - return 'void'; - case 'StringTypeAnnotation': - return wrapIntoNullableIfNeeded('NSString *'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return wrapIntoNullableIfNeeded('NSNumber *'); - case 'BooleanTypeAnnotation': - return typeAnnotation.nullable ? 'NSNumber * _Nullable' : 'BOOL'; - case 'GenericObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); - case 'ArrayTypeAnnotation': - return wrapIntoNullableIfNeeded('NSArray> *'); - case 'ObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error(createErrorMessage(typeAnnotation.type)); - } -} - -function handleArrayOfObjects( - objectForGeneratingStructs: Array, - propOrParam: FunctionTypeAnnotationParam, - name: string, -) { - if ( - propOrParam.typeAnnotation.type === 'ArrayTypeAnnotation' && - propOrParam.typeAnnotation.elementType - ) { - const typeAnnotation = propOrParam.typeAnnotation.elementType; - const type = typeAnnotation.type; - - if ( - type === 'ObjectTypeAnnotation' && - typeAnnotation.properties && - typeAnnotation.properties.length > 0 - ) { - objectForGeneratingStructs.push({ - name, - object: { - type: 'ObjectTypeAnnotation', - properties: typeAnnotation.properties, - }, - }); - } - } -} - -const methodImplementationTemplate = - '- (::_RETURN_VALUE_::) ::_PROPERTY_NAME_::::_ARGS_::;'; - -module.exports = { - generate( - libraryName: string, - schema: SchemaType, - moduleSpecName: string, - ): FilesOutput { - const nativeModules = Object.keys(schema.modules) - .sort() - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, components) => Object.assign(acc, components), {}); - - const modules = Object.keys(nativeModules) - .map(name => moduleTemplate.replace(/::_MODULE_NAME_::/g, name)) - .join('\n'); - - const protocols = Object.keys(nativeModules) - .sort() - .map(name => { - const objectForGeneratingStructs: Array = []; - const {aliases, properties} = nativeModules[name]; - const implementations = properties - .map(prop => { - const nativeArgs = prop.typeAnnotation.params - .map((param, i) => { - let paramObjCType; - if ( - param.typeAnnotation.type === 'ObjectTypeAnnotation' && - param.typeAnnotation.properties - ) { - const variableName = - capitalizeFirstLetter(prop.name) + - capitalizeFirstLetter(param.name); - const structName = 'Spec' + variableName; - objectForGeneratingStructs.push({ - name: structName, - object: { - type: 'ObjectTypeAnnotation', - properties: param.typeAnnotation.properties, - }, - }); - paramObjCType = getNamespacedStructName(structName) + ' &'; - - param.typeAnnotation.properties.map(aProp => { - return handleArrayOfObjects( - objectForGeneratingStructs, - aProp, - 'Spec' + - capitalizeFirstLetter(prop.name) + - capitalizeFirstLetter(param.name) + - capitalizeFirstLetter(aProp.name) + - 'Element', - ); - }); - } else if ( - param.typeAnnotation.type === 'TypeAliasTypeAnnotation' - ) { - const typeAnnotation = getTypeAliasTypeAnnotation( - param.typeAnnotation.name, - aliases, - ); - if (typeAnnotation.type === 'ObjectTypeAnnotation') { - paramObjCType = - getNamespacedStructName(param.typeAnnotation.name) + ' &'; - } else { - throw Error( - `Unsupported type for "${param.typeAnnotation.name}". Found: ${typeAnnotation.type}`, - ); - } - } else { - paramObjCType = translatePrimitiveJSTypeToObjCType( - param, - typeName => - `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, - aliases, - ); - - handleArrayOfObjects( - objectForGeneratingStructs, - param, - 'Spec' + - capitalizeFirstLetter(prop.name) + - capitalizeFirstLetter(param.name) + - 'Element', - ); - } - return `${i === 0 ? '' : param.name}:(${paramObjCType})${ - param.name - }`; - }) - .join('\n ') - .concat(callbackArgs(prop)); - const {returnTypeAnnotation} = prop.typeAnnotation; - if ( - returnTypeAnnotation.type === 'ObjectTypeAnnotation' && - returnTypeAnnotation.properties - ) { - objectForGeneratingStructs.push({ - name: 'Spec' + capitalizeFirstLetter(prop.name) + 'ReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: returnTypeAnnotation.properties, - }, - }); - } - const implementation = methodImplementationTemplate - .replace('::_PROPERTY_NAME_::', prop.name) - .replace( - '::_RETURN_VALUE_::', - translatePrimitiveJSTypeToObjCTypeForReturn( - returnTypeAnnotation, - typeName => - `Unsupported return type for ${prop.name}. Found: ${typeName}`, - ), - ) - .replace('::_ARGS_::', nativeArgs); - if (prop.name === 'getConstants') { - if ( - prop.typeAnnotation.returnTypeAnnotation.properties && - prop.typeAnnotation.returnTypeAnnotation.properties.length === 0 - ) { - return ''; - } - return constants.replace(/::_MODULE_NAME_::/, name); - } - return implementation; - }) - .join('\n'); - - Object.keys(aliases) - .reverse() - .map((aliasName, i) => { - const alias = aliases[aliasName]; - - let paramObjCType = ''; - - switch (alias.type) { - case 'ObjectTypeAnnotation': - if (alias.properties) { - objectForGeneratingStructs.push({ - name: aliasName, - object: { - type: 'ObjectTypeAnnotation', - properties: alias.properties, - }, - }); - paramObjCType = getNamespacedStructName(alias.name) + ' &'; - } - break; - default: - throw Error( - `Unsupported type for "${aliasName}". Found: ${alias.type}`, - ); - } - return `${i === 0 ? '' : aliasName}:(${paramObjCType})${aliasName}`; - }) - .join('\n'); - - return protocolTemplate - .replace( - /::_STRUCTS_::/g, - translateObjectsForStructs( - objectForGeneratingStructs, - name, - aliases, - ), - ) - .replace(/::_MODULE_PROPERTIES_::/g, implementations) - .replace(/::_MODULE_NAME_::/g, name) - .replace('::_PROPERTIES_MAP_::', ''); - }) - .join('\n'); - - const fileName = `${moduleSpecName}.h`; - const replacedTemplate = template - .replace(/::_MODULES_::/g, modules) - .replace(/::_PROTOCOLS_::/g, protocols); - - return new Map([[fileName, replacedTemplate]]); - }, -}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js deleted file mode 100644 index 53a0585886e3dd..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js +++ /dev/null @@ -1,320 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict - * @format - */ - -'use strict'; - -import type {SchemaType, NativeModuleShape} from '../../CodegenSchema'; - -const {capitalizeFirstLetter} = require('./ObjCppUtils/GenerateStructs'); -const {flatObjects} = require('./ObjCppUtils/Utils'); -const {getTypeAliasTypeAnnotation} = require('./Utils'); - -type FilesOutput = Map; - -const propertyHeaderTemplate = - ' static facebook::jsi::Value __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {'; - -const propertyCastTemplate = `static_cast(turboModule) - .invokeObjCMethod(rt, ::_KIND_::, "::_PROPERTY_NAME_::", @selector(::_PROPERTY_NAME_::::_ARGS_::), args, count);`; - -const propertyTemplate = ` -${propertyHeaderTemplate} - return ${propertyCastTemplate} - }`; - -const propertyDefTemplate = - ' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::};'; - -const moduleTemplate = ` - ::_TURBOMODULE_METHOD_INVOKERS_:: - - Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - ::_PROPERTIES_MAP_::::_CONVERSION_SELECTORS_:: - }`.trim(); - -const getterTemplate = ` -@implementation RCTCxxConvert (Native::_MODULE_NAME_::_::_GETTER_NAME_::) -+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_GETTER_NAME_:::(id)json -{ - return facebook::react::managedPointer(json); -} -@end -`; - -const argConvertionTemplate = - '\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_::_SELECTOR_NAME_:::");'; - -const template = ` -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * ${'@'}generated by codegen project: GenerateModuleMm.js - */ - -#include <::_INCLUDE_::> -#import - -::_GETTERS_:: -namespace facebook { - namespace react { -::_MODULES_:: - } // namespace react -} // namespace facebook -`; - -function translateReturnTypeToKind(typeAnnotation): string { - switch (typeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { - case 'RootTag': - return 'NumberKind'; - default: - (typeAnnotation.name: empty); - throw new Error( - `Invalid ReservedFunctionValueTypeName name, got ${typeAnnotation.name}`, - ); - } - case 'VoidTypeAnnotation': - return 'VoidKind'; - case 'StringTypeAnnotation': - return 'StringKind'; - case 'BooleanTypeAnnotation': - return 'BooleanKind'; - case 'NumberTypeAnnotation': - case 'DoubleTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return 'NumberKind'; - case 'PromiseTypeAnnotation': - return 'PromiseKind'; - case 'GenericObjectTypeAnnotation': - case 'ObjectTypeAnnotation': - return 'ObjectKind'; - case 'ArrayTypeAnnotation': - return 'ArrayKind'; - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error( - `Unknown prop type for returning value, found: ${typeAnnotation.type}"`, - ); - } -} - -function translateMethodForImplementation(property): string { - const {returnTypeAnnotation} = property.typeAnnotation; - - const numberOfParams = - property.typeAnnotation.params.length + - (returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? 2 : 0); - const translatedArguments = property.typeAnnotation.params - .map(param => param.name) - .concat( - returnTypeAnnotation.type === 'PromiseTypeAnnotation' - ? ['resolve', 'reject'] - : [], - ) - .slice(1) - .join(':') - .concat(':'); - if ( - property.name === 'getConstants' && - returnTypeAnnotation.type === 'ObjectTypeAnnotation' && - returnTypeAnnotation.properties && - returnTypeAnnotation.properties.length === 0 - ) { - return ''; - } - return propertyTemplate - .replace(/::_KIND_::/g, translateReturnTypeToKind(returnTypeAnnotation)) - .replace(/::_PROPERTY_NAME_::/g, property.name) - .replace( - /::_ARGS_::/g, - numberOfParams === 0 - ? '' - : (numberOfParams === 1 ? '' : ':') + translatedArguments, - ); -} - -module.exports = { - generate( - libraryName: string, - schema: SchemaType, - moduleSpecName: string, - ): FilesOutput { - const nativeModules: {[name: string]: NativeModuleShape, ...} = Object.keys( - schema.modules, - ) - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, modules) => Object.assign(acc, modules), {}); - - const gettersImplementations = Object.keys(nativeModules) - .reduce((acc, moduleName: string) => { - const module: NativeModuleShape = nativeModules[moduleName]; - return acc.concat( - flatObjects( - module.properties - .reduce((moduleAcc, property) => { - const {returnTypeAnnotation} = property.typeAnnotation; - if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') { - const {properties} = returnTypeAnnotation; - if (properties) { - moduleAcc.push({ - name: - 'Spec' + - capitalizeFirstLetter(property.name) + - 'ReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: properties, - }, - }); - } - } - if (property.typeAnnotation.params) { - return moduleAcc.concat( - property.typeAnnotation.params - .map(param => { - if ( - param.typeAnnotation.type === 'ObjectTypeAnnotation' - ) { - const {properties} = param.typeAnnotation; - if (properties) { - return { - name: - 'Spec' + - capitalizeFirstLetter(property.name) + - capitalizeFirstLetter(param.name), - object: { - type: 'ObjectTypeAnnotation', - properties: properties, - }, - }; - } - } - }) - .filter(Boolean), - ); - } - return moduleAcc; - }, []) - .concat( - Object.keys(module.aliases).map(aliasName => { - const alias = getTypeAliasTypeAnnotation( - aliasName, - module.aliases, - ); - return { - name: aliasName, - object: {type: alias.type, properties: alias.properties}, - }; - }), - ), - false, - module.aliases, - ) - .map(object => - getterTemplate - .replace(/::_GETTER_NAME_::/g, object.name) - .replace(/::_MODULE_NAME_::/g, moduleName), - ) - .join('\n'), - ); - }, []) - .join('\n'); - - const modules = Object.keys(nativeModules) - .map(name => { - const {aliases, properties} = nativeModules[name]; - const translatedMethods = properties - .map(property => translateMethodForImplementation(property)) - .join('\n'); - return moduleTemplate - .replace(/::_TURBOMODULE_METHOD_INVOKERS_::/g, translatedMethods) - .replace( - '::_PROPERTIES_MAP_::', - properties - .map( - ({ - name: propertyName, - typeAnnotation: {params, returnTypeAnnotation}, - }) => - propertyName === 'getConstants' && - returnTypeAnnotation.type === 'ObjectTypeAnnotation' && - returnTypeAnnotation.properties && - returnTypeAnnotation.properties.length === 0 - ? '' - : propertyDefTemplate - .replace(/::_PROPERTY_NAME_::/g, propertyName) - .replace(/::_ARGS_COUNT_::/g, params.length.toString()), - ) - .join('\n'), - ) - .replace( - '::_CONVERSION_SELECTORS_::', - properties - .map(({name: propertyName, typeAnnotation: {params}}) => - params - .map((param, index) => { - const typeAnnotation = - param.typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation( - param.typeAnnotation.name, - aliases, - ) - : param.typeAnnotation; - const selectorName = - param.typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? param.typeAnnotation.name - : 'Spec' + - capitalizeFirstLetter(propertyName) + - capitalizeFirstLetter(param.name); - - if ( - typeAnnotation.type === 'ObjectTypeAnnotation' && - typeAnnotation.properties - ) { - return argConvertionTemplate - .replace('::_SELECTOR_NAME_::', selectorName) - .replace('::_ARG_NUMBER_::', index.toString()) - .replace('::_ARG_NAME_::', propertyName); - } - - return ''; - }) - .join(''), - ) - .join(''), - ) - .replace(/::_MODULE_NAME_::/g, name); - }) - .join('\n'); - - const fileName = `${moduleSpecName}-generated.mm`; - const replacedTemplate = template - .replace(/::_GETTERS_::/g, gettersImplementations) - .replace(/::_MODULES_::/g, modules) - .replace(/::_LIBRARY_NAME_::/g, libraryName) - .replace(/::_INCLUDE_::/g, `${moduleSpecName}/${moduleSpecName}.h`); - return new Map([[fileName, replacedTemplate]]); - }, -}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js new file mode 100644 index 00000000000000..71855f15f4f864 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js @@ -0,0 +1,191 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type { + Required, + NativeModuleObjectTypeAnnotation, + NativeModuleStringTypeAnnotation, + NativeModuleNumberTypeAnnotation, + NativeModuleInt32TypeAnnotation, + NativeModuleDoubleTypeAnnotation, + NativeModuleFloatTypeAnnotation, + NativeModuleBooleanTypeAnnotation, + NativeModuleGenericObjectTypeAnnotation, + NativeModuleReservedFunctionValueTypeAnnotation, + NativeModuleTypeAliasTypeAnnotation, + NativeModuleArrayTypeAnnotation, + NativeModuleBaseTypeAnnotation, +} from '../../../CodegenSchema'; + +import type {AliasResolver} from '../Utils'; + +const {capitalize} = require('./Utils'); + +type StructContext = 'CONSTANTS' | 'REGULAR'; + +export type RegularStruct = $ReadOnly<{| + context: 'REGULAR', + name: string, + properties: $ReadOnlyArray, +|}>; + +export type ConstantsStruct = $ReadOnly<{| + context: 'CONSTANTS', + name: string, + properties: $ReadOnlyArray, +|}>; + +export type Struct = RegularStruct | ConstantsStruct; + +export type StructProperty = $ReadOnly<{| + name: string, + optional: boolean, + typeAnnotation: StructTypeAnnotation, +|}>; + +export type StructTypeAnnotation = + | NativeModuleStringTypeAnnotation + | NativeModuleNumberTypeAnnotation + | NativeModuleInt32TypeAnnotation + | NativeModuleDoubleTypeAnnotation + | NativeModuleFloatTypeAnnotation + | NativeModuleBooleanTypeAnnotation + | NativeModuleGenericObjectTypeAnnotation + | NativeModuleReservedFunctionValueTypeAnnotation + | NativeModuleTypeAliasTypeAnnotation + | NativeModuleArrayTypeAnnotation; + +class StructCollector { + _structs: Map = new Map(); + + process( + structName: string, + structContext: StructContext, + resolveAlias: AliasResolver, + typeAnnotation: NativeModuleBaseTypeAnnotation, + ): StructTypeAnnotation { + switch (typeAnnotation.type) { + case 'ObjectTypeAnnotation': { + this._insertStruct(structName, structContext, resolveAlias, { + ...typeAnnotation, + // The nullability status of this struct is recorded in the type-alias we create for it below. + nullable: false, + }); + return { + type: 'TypeAliasTypeAnnotation', + name: structName, + nullable: typeAnnotation.nullable, + }; + } + case 'ArrayTypeAnnotation': { + if (typeAnnotation.elementType == null) { + return { + type: 'ArrayTypeAnnotation', + nullable: typeAnnotation.nullable, + }; + } + + return { + type: 'ArrayTypeAnnotation', + nullable: typeAnnotation.nullable, + elementType: this.process( + structName + 'Element', + structContext, + resolveAlias, + typeAnnotation.elementType, + ), + }; + } + case 'TypeAliasTypeAnnotation': { + this._insertAlias(typeAnnotation.name, structContext, resolveAlias); + return typeAnnotation; + } + default: { + return typeAnnotation; + } + } + } + + _insertAlias( + aliasName: string, + structContext: StructContext, + resolveAlias: AliasResolver, + ): void { + const usedStruct = this._structs.get(aliasName); + if (usedStruct == null) { + this._insertStruct( + aliasName, + structContext, + resolveAlias, + resolveAlias(aliasName), + ); + } else if (usedStruct.context !== structContext) { + throw new Error( + `Tried to use alias '${aliasName}' in a getConstants() return type and inside a regular struct.`, + ); + } + } + + _insertStruct( + structName: string, + structContext: StructContext, + resolveAlias: AliasResolver, + objectTypeAnnotation: Required, + ): void { + const properties = objectTypeAnnotation.properties.map(property => { + const {typeAnnotation: propertyTypeAnnotation} = property; + const propertyStructName = structName + capitalize(property.name); + + return { + ...property, + typeAnnotation: this.process( + propertyStructName, + structContext, + resolveAlias, + propertyTypeAnnotation, + ), + }; + }); + + switch (structContext) { + case 'REGULAR': + this._structs.set(structName, { + name: structName, + context: 'REGULAR', + properties: properties, + }); + break; + case 'CONSTANTS': + this._structs.set(structName, { + name: structName, + context: 'CONSTANTS', + properties: properties, + }); + break; + default: + (structContext: empty); + throw new Error(`Detected an invalid struct context: ${structContext}`); + } + } + + getAllStructs(): $ReadOnlyArray { + return [...this._structs.values()]; + } + + getStruct(name: string): ?Struct { + return this._structs.get(name); + } +} + +module.exports = { + StructCollector, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js new file mode 100644 index 00000000000000..0b989b12e03d02 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js @@ -0,0 +1,36 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type {StructProperty} from './StructCollector'; + +function capitalize(string: string): string { + return string.charAt(0).toUpperCase() + string.slice(1); +} +function getSafePropertyName(property: StructProperty): string { + if (property.name === 'id') { + return `${property.name}_`; + } + return property.name; +} + +function getNamespacedStructName( + moduleName: string, + structName: string, +): string { + return `JS::Native${moduleName}::${structName}`; +} + +module.exports = { + capitalize, + getSafePropertyName, + getNamespacedStructName, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js new file mode 100644 index 00000000000000..27a71f43a32cf1 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js @@ -0,0 +1,263 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +const { + capitalize, + getSafePropertyName, + getNamespacedStructName, +} = require('../Utils'); + +import type {StructTypeAnnotation, ConstantsStruct} from '../StructCollector'; +import type {StructSerilizationOutput} from './serializeStruct'; + +const StructTemplate = ({ + moduleName, + structName, + builderInputProps, +}: $ReadOnly<{| + moduleName: string, + structName: string, + builderInputProps: string, +|}>) => ` +namespace JS { + namespace Native${moduleName} { + struct ${structName} { + + struct Builder { + struct Input { + ${builderInputProps} + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ${structName} */ + Builder(${structName} i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ${structName} fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ${structName}(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +}`; + +const MethodTemplate = ({ + moduleName, + structName, + properties, +}: $ReadOnly<{| + moduleName: string, + structName: string, + properties: string, +|}>) => ` +inline JS::Native${moduleName}::${structName}::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; +${properties} + return d; +}) {} +inline JS::Native${moduleName}::${structName}::Builder::Builder(${structName} i) : _factory(^{ + return i.unsafeRawValue(); +}) {}`; + +function toObjCType( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + isOptional: boolean = false, +): string { + const isRequired = !typeAnnotation.nullable && !isOptional; + const wrapFollyOptional = (type: string) => { + return isRequired ? type : `folly::Optional<${type}>`; + }; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapFollyOptional('double'); + default: + (typeAnnotation.name: empty); + throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + } + case 'StringTypeAnnotation': + return 'NSString *'; + case 'NumberTypeAnnotation': + return wrapFollyOptional('double'); + case 'FloatTypeAnnotation': + return wrapFollyOptional('double'); + case 'Int32TypeAnnotation': + return wrapFollyOptional('double'); + case 'DoubleTypeAnnotation': + return wrapFollyOptional('double'); + case 'BooleanTypeAnnotation': + return wrapFollyOptional('bool'); + case 'GenericObjectTypeAnnotation': + return isRequired ? 'id ' : 'id _Nullable '; + case 'ArrayTypeAnnotation': + if (typeAnnotation.elementType == null) { + return isRequired ? 'id ' : 'id _Nullable '; + } + + return wrapFollyOptional( + `std::vector<${toObjCType(moduleName, typeAnnotation.elementType)}>`, + ); + case 'TypeAliasTypeAnnotation': + const structName = capitalize(typeAnnotation.name); + const namespacedStructName = getNamespacedStructName( + moduleName, + structName, + ); + return wrapFollyOptional(`${namespacedStructName}::Builder`); + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } +} + +function toObjCValue( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + value: string, + depth: number, + isOptional: boolean = false, +): string { + const isRequired = !isOptional && !typeAnnotation.nullable; + + function wrapPrimitive(type: string) { + return !isRequired + ? `${value}.hasValue() ? @((${type})${value}.value()) : nil` + : `@(${value})`; + } + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapPrimitive('double'); + default: + (typeAnnotation.name: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } + case 'StringTypeAnnotation': + return value; + case 'NumberTypeAnnotation': + return wrapPrimitive('double'); + case 'FloatTypeAnnotation': + return wrapPrimitive('double'); + case 'Int32TypeAnnotation': + return wrapPrimitive('double'); + case 'DoubleTypeAnnotation': + return wrapPrimitive('double'); + case 'BooleanTypeAnnotation': + return wrapPrimitive('BOOL'); + case 'GenericObjectTypeAnnotation': + return value; + case 'ArrayTypeAnnotation': + const {elementType} = typeAnnotation; + if (elementType == null) { + return value; + } + + const localVarName = `el${'_'.repeat(depth + 1)}`; + const elementObjCType = toObjCType(moduleName, elementType); + const elementObjCValue = toObjCValue( + moduleName, + elementType, + localVarName, + depth + 1, + ); + + const RCTConvertVecToArray = transformer => { + return `RCTConvert${ + !isRequired ? 'Optional' : '' + }VecToArray(${value}, ${transformer})`; + }; + + return RCTConvertVecToArray( + `^id(${elementObjCType} ${localVarName}) { return ${elementObjCValue}; }`, + ); + case 'TypeAliasTypeAnnotation': + return !isRequired + ? `${value}.hasValue() ? ${value}.value().buildUnsafeRawValue() : nil` + : `${value}.buildUnsafeRawValue()`; + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC value: ${typeAnnotation.type}"`, + ); + } +} + +function serializeConstantsStruct( + moduleName: string, + struct: ConstantsStruct, +): StructSerilizationOutput { + const declaration = StructTemplate({ + moduleName, + structName: struct.name, + builderInputProps: struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const objCType = toObjCType(moduleName, typeAnnotation, optional); + + if (!optional) { + return `RCTRequired<${objCType}> ${propName};`; + } + + const space = ' '.repeat(objCType.endsWith('*') ? 0 : 1); + return `${objCType}${space}${propName};`; + }) + .join('\n '), + }); + + const methods = MethodTemplate({ + moduleName, + structName: struct.name, + properties: struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const objCValue = toObjCValue( + moduleName, + typeAnnotation, + propName, + 0, + optional, + ); + + let varDecl = `auto ${propName} = i.${propName}`; + if (!optional) { + varDecl += '.get()'; + } + + const assignment = `d[@"${propName}"] = ` + objCValue; + return ` ${varDecl};\n ${assignment};`; + }) + .join('\n'), + }); + + return {declaration, methods}; +} + +module.exports = { + serializeConstantsStruct, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js new file mode 100644 index 00000000000000..ce7b5f12d4f5bb --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js @@ -0,0 +1,251 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +const { + capitalize, + getSafePropertyName, + getNamespacedStructName, +} = require('../Utils'); + +import type {StructTypeAnnotation, RegularStruct} from '../StructCollector'; +import type {StructSerilizationOutput} from './serializeStruct'; + +const StructTemplate = ({ + moduleName, + structName, + structProperties, +}: $ReadOnly<{| + moduleName: string, + structName: string, + structProperties: string, +|}>) => ` +namespace JS { + namespace Native${moduleName} { + struct ${structName} { + ${structProperties} + + ${structName}(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (Native${moduleName}_${structName}) ++ (RCTManagedPointer *)JS_Native${moduleName}_${structName}:(id)json; +@end +`; + +const MethodTemplate = ({ + returnType, + returnValue, + moduleName, + structName, + propertyName, +}: $ReadOnly<{| + returnType: string, + returnValue: string, + moduleName: string, + structName: string, + propertyName: string, +|}>) => ` +inline ${returnType}JS::Native${moduleName}::${structName}::${propertyName}() const +{ + id const p = _v[@"${propertyName}"]; + return ${returnValue}; +} +`; + +function toObjCType( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + isOptional: boolean = false, +): string { + const isRequired = !typeAnnotation.nullable && !isOptional; + const wrapFollyOptional = (type: string) => { + return isRequired ? type : `folly::Optional<${type}>`; + }; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapFollyOptional('double'); + default: + (typeAnnotation.name: empty); + throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + } + case 'StringTypeAnnotation': + return 'NSString *'; + case 'NumberTypeAnnotation': + return wrapFollyOptional('double'); + case 'FloatTypeAnnotation': + return wrapFollyOptional('double'); + case 'Int32TypeAnnotation': + return wrapFollyOptional('double'); + case 'DoubleTypeAnnotation': + return wrapFollyOptional('double'); + case 'BooleanTypeAnnotation': + return wrapFollyOptional('bool'); + case 'GenericObjectTypeAnnotation': + return isRequired ? 'id ' : 'id _Nullable'; + case 'ArrayTypeAnnotation': + if (typeAnnotation.elementType == null) { + return isRequired ? 'id ' : 'id _Nullable'; + } + return wrapFollyOptional( + `facebook::react::LazyVector<${toObjCType( + moduleName, + typeAnnotation.elementType, + )}>`, + ); + case 'TypeAliasTypeAnnotation': + const structName = capitalize(typeAnnotation.name); + const namespacedStructName = getNamespacedStructName( + moduleName, + structName, + ); + return wrapFollyOptional(namespacedStructName); + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } +} + +function toObjCValue( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + value: string, + depth: number, + isOptional: boolean = false, +): string { + const isRequired = !typeAnnotation.nullable && !isOptional; + const RCTBridgingTo = (type: string, arg?: string) => { + const args = [value, arg].filter(Boolean).join(', '); + return isRequired + ? `RCTBridgingTo${type}(${args})` + : `RCTBridgingToOptional${type}(${args})`; + }; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return RCTBridgingTo('Double'); + default: + (typeAnnotation.name: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } + case 'StringTypeAnnotation': + return RCTBridgingTo('String'); + case 'NumberTypeAnnotation': + return RCTBridgingTo('Double'); + case 'FloatTypeAnnotation': + return RCTBridgingTo('Double'); + case 'Int32TypeAnnotation': + return RCTBridgingTo('Double'); + case 'DoubleTypeAnnotation': + return RCTBridgingTo('Double'); + case 'BooleanTypeAnnotation': + return RCTBridgingTo('Bool'); + case 'GenericObjectTypeAnnotation': + return value; + case 'ArrayTypeAnnotation': + const {elementType} = typeAnnotation; + if (elementType == null) { + return value; + } + + const localVarName = `itemValue_${depth}`; + const elementObjCType = toObjCType(moduleName, elementType); + const elementObjCValue = toObjCValue( + moduleName, + elementType, + localVarName, + depth + 1, + ); + + return RCTBridgingTo( + 'Vec', + `^${elementObjCType}(id ${localVarName}) { return ${elementObjCValue}; }`, + ); + case 'TypeAliasTypeAnnotation': + const structName = capitalize(typeAnnotation.name); + const namespacedStructName = getNamespacedStructName( + moduleName, + structName, + ); + + return !isRequired + ? `(p == nil ? folly::none : folly::make_optional(${namespacedStructName}(p)))` + : `${namespacedStructName}(p)`; + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC value: ${typeAnnotation.type}"`, + ); + } +} + +function serializeRegularStruct( + moduleName: string, + struct: RegularStruct, +): StructSerilizationOutput { + const declaration = StructTemplate({ + moduleName: moduleName, + structName: struct.name, + structProperties: struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const returnType = toObjCType(moduleName, typeAnnotation, optional); + + const padding = ' '.repeat(returnType.endsWith('*') ? 0 : 1); + return `${returnType}${padding}${propName}() const;`; + }) + .join('\n '), + }); + + const methods = struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const returnType = toObjCType(moduleName, typeAnnotation, optional); + const returnValue = toObjCValue( + moduleName, + typeAnnotation, + 'p', + 0, + optional, + ); + + const padding = ' '.repeat(returnType.endsWith('*') ? 0 : 1); + return MethodTemplate({ + moduleName, + structName: struct.name, + returnType: returnType + padding, + returnValue: returnValue, + propertyName: propName, + }); + }) + .join('\n'); + + return {methods, declaration}; +} + +module.exports = { + serializeRegularStruct, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js new file mode 100644 index 00000000000000..fe2355333b3a83 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js @@ -0,0 +1,35 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type {Struct} from '../StructCollector'; + +const {serializeConstantsStruct} = require('./serializeConstantsStruct'); +const {serializeRegularStruct} = require('./serializeRegularStruct'); + +export type StructSerilizationOutput = $ReadOnly<{| + methods: string, + declaration: string, +|}>; + +function serializeStruct( + moduleName: string, + struct: Struct, +): StructSerilizationOutput { + if (struct.context === 'REGULAR') { + return serializeRegularStruct(moduleName, struct); + } + return serializeConstantsStruct(moduleName, struct); +} + +module.exports = { + serializeStruct, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js new file mode 100644 index 00000000000000..0f1852415b206c --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js @@ -0,0 +1,210 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type {SchemaType} from '../../../CodegenSchema'; +import type {MethodSerializationOutput} from './serializeMethod'; + +const {createAliasResolver, getModules} = require('../Utils'); + +const {StructCollector} = require('./StructCollector'); +const {serializeStruct} = require('./header/serializeStruct'); +const {serializeMethod} = require('./serializeMethod'); +const {serializeModuleSource} = require('./source/serializeModule'); + +type FilesOutput = Map; + +const ModuleDeclarationTemplate = ({ + moduleName, + structDeclarations, + protocolMethods, +}: $ReadOnly<{| + moduleName: string, + structDeclarations: string, + protocolMethods: string, +|}>) => ` +${structDeclarations} +@protocol Native${moduleName}Spec + +${protocolMethods} + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module '${moduleName}' + */ + class JSI_EXPORT Native${moduleName}SpecJSI : public ObjCTurboModule { + public: + Native${moduleName}SpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +`; + +const HeaderFileTemplate = ({ + moduleDeclarations, + structInlineMethods, +}: $ReadOnly<{| + moduleDeclarations: string, + structInlineMethods: string, +|}>) => ` +/** + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * ${'@'}generated by codegen project: GenerateModuleHObjCpp.js + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif + +#import + +#import + +#import + +#import +#import +#import + +#import +#import +#import + +#import + +${moduleDeclarations} + +${structInlineMethods} +`; + +const SourceFileTemplate = ({ + headerFileName, + moduleImplementations, +}: $ReadOnly<{| + headerFileName: string, + moduleImplementations: string, +|}>) => ` +/** + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * ${'@'}generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. + */ + +#import "${headerFileName}" + +${moduleImplementations} +`; + +module.exports = { + generate( + libraryName: string, + schema: SchemaType, + moduleSpecName: string, + ): FilesOutput { + const nativeModules = getModules(schema); + + const moduleDeclarations: Array = []; + const structInlineMethods: Array = []; + const moduleImplementations: Array = []; + + const moduleNames: Array = Object.keys(nativeModules).sort(); + for (const moduleName of moduleNames) { + const {aliases, properties} = nativeModules[moduleName]; + const resolveAlias = createAliasResolver(aliases); + const structCollector = new StructCollector(); + + const methodSerializations: Array = []; + const serializeProperty = property => { + methodSerializations.push( + ...serializeMethod( + moduleName, + property, + structCollector, + resolveAlias, + ), + ); + }; + + /** + * Note: As we serialize NativeModule methods, we insert structs into + * StructCollector, as we encounter them. + */ + properties + .filter(property => property.name !== 'getConstants') + .forEach(serializeProperty); + properties + .filter(property => property.name === 'getConstants') + .forEach(serializeProperty); + + const generatedStructs = structCollector.getAllStructs(); + const structStrs = []; + const methodStrs = []; + + for (const struct of generatedStructs) { + const {methods, declaration} = serializeStruct(moduleName, struct); + structStrs.push(declaration); + methodStrs.push(methods); + } + + moduleDeclarations.push( + ModuleDeclarationTemplate({ + moduleName: moduleName, + structDeclarations: structStrs.join('\n'), + protocolMethods: methodSerializations + .map(({protocolMethod}) => protocolMethod) + .join('\n'), + }), + ); + + structInlineMethods.push(methodStrs.join('\n')); + + moduleImplementations.push( + serializeModuleSource( + moduleName, + generatedStructs, + methodSerializations.filter( + ({selector}) => selector !== 'constantsToExport', + ), + ), + ); + } + + const headerFileName = `${moduleSpecName}.h`; + const headerFile = HeaderFileTemplate({ + moduleDeclarations: moduleDeclarations.join('\n'), + structInlineMethods: structInlineMethods.join('\n'), + }); + + const sourceFileName = `${moduleSpecName}-generated.mm`; + const sourceFile = SourceFileTemplate({ + headerFileName, + moduleImplementations: moduleImplementations.join('\n'), + }); + + return new Map([ + [headerFileName, headerFile], + [sourceFileName, sourceFile], + ]); + }, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js new file mode 100644 index 00000000000000..6fe0c47b288e9a --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -0,0 +1,413 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type { + NativeModuleMethodParamSchema, + NativeModuleReturnTypeAnnotation, + NativeModulePropertySchema, +} from '../../../CodegenSchema'; + +import type {AliasResolver} from '../Utils'; + +const invariant = require('invariant'); +const {StructCollector} = require('./StructCollector'); +const {capitalize, getNamespacedStructName} = require('./Utils'); + +const ProtocolMethodTemplate = ({ + returnObjCType, + methodName, + params, +}: $ReadOnly<{| + returnObjCType: string, + methodName: string, + params: string, +|}>) => `- (${returnObjCType})${methodName}${params};`; + +export type StructParameterRecord = $ReadOnly<{| + paramIndex: number, + structName: string, +|}>; + +type ReturnJSType = + | 'VoidKind' + | 'PromiseKind' + | 'ObjectKind' + | 'ArrayKind' + | 'NumberKind' + | 'StringKind'; + +export type MethodSerializationOutput = $ReadOnly<{| + methodName: string, + protocolMethod: string, + selector: string, + structParamRecords: $ReadOnlyArray, + returnJSType: ReturnJSType, +|}>; + +function serializeMethod( + moduleName: string, + property: NativeModulePropertySchema, + structCollector: StructCollector, + resolveAlias: AliasResolver, +): $ReadOnlyArray { + const { + name: methodName, + typeAnnotation: {params, returnTypeAnnotation}, + } = property; + + if (methodName === 'getConstants') { + return serializeConstantsProtocolMethods( + moduleName, + property, + structCollector, + resolveAlias, + ); + } + + const methodParams: Array<{|paramName: string, objCType: string|}> = []; + const structParamRecords: Array = []; + + params.forEach((param, index) => { + const structName = `Spec${capitalize(methodName)}${capitalize(param.name)}`; + const {objCType, isStruct} = getParamObjCType( + moduleName, + methodName, + param, + structName, + structCollector, + resolveAlias, + ); + + methodParams.push({paramName: param.name, objCType}); + + if (isStruct) { + structParamRecords.push({paramIndex: index, structName}); + } + }); + + if (returnTypeAnnotation.type === 'PromiseTypeAnnotation') { + methodParams.push( + {paramName: 'resolve', objCType: 'RCTPromiseResolveBlock'}, + {paramName: 'reject', objCType: 'RCTPromiseRejectBlock'}, + ); + } + + /** + * Build Protocol Method + **/ + const returnObjCType = getReturnObjCType(methodName, returnTypeAnnotation); + const paddingMax = `- (${returnObjCType})${methodName}`.length; + + const objCParams = methodParams.reduce( + ($objCParams, {objCType, paramName}, i) => { + const rhs = `(${objCType})${paramName}`; + const padding = ' '.repeat(Math.max(0, paddingMax - paramName.length)); + return i === 0 + ? `:${rhs}` + : `${$objCParams}\n${padding}${paramName}:${rhs}`; + }, + '', + ); + + const protocolMethod = ProtocolMethodTemplate({ + methodName, + returnObjCType, + params: objCParams, + }); + + /** + * Build ObjC Selector + */ + const selector = methodParams + .map(({paramName}) => paramName) + .reduce(($selector, paramName, i) => { + return i === 0 ? `${$selector}:` : `${$selector}${paramName}:`; + }, methodName); + + /** + * Build JS Return type + */ + const returnJSType = getReturnJSType(methodName, returnTypeAnnotation); + + return [ + { + methodName, + protocolMethod, + selector: `@selector(${selector})`, + structParamRecords, + returnJSType, + }, + ]; +} + +function getParamObjCType( + moduleName: string, + methodName: string, + param: NativeModuleMethodParamSchema, + structName: string, + structCollector: StructCollector, + resolveAlias: AliasResolver, +): $ReadOnly<{|objCType: string, isStruct: boolean|}> { + const {name: paramName, typeAnnotation} = param; + const notRequired = param.optional || typeAnnotation.nullable; + + function wrapIntoNullableIfNeeded(generatedType: string) { + return typeAnnotation.nullable + ? `${generatedType} _Nullable` + : generatedType; + } + + const isStruct = (objCType: string) => ({ + isStruct: true, + objCType, + }); + + const notStruct = (objCType: string) => ({ + isStruct: false, + objCType, + }); + + // Handle types that can only be in parameters + switch (typeAnnotation.type) { + case 'FunctionTypeAnnotation': { + return notStruct('RCTResponseSenderBlock'); + } + case 'ArrayTypeAnnotation': { + /** + * Array in params always codegen NSArray * + * + * TODO(T73933406): Support codegen for Arrays of structs and primitives + * + * For example: + * Array => NSArray + * type Animal = {||}; + * Array => NSArray, etc. + */ + return notStruct(wrapIntoNullableIfNeeded('NSArray *')); + } + } + + const structTypeAnnotation = structCollector.process( + structName, + 'REGULAR', + resolveAlias, + typeAnnotation, + ); + + invariant( + structTypeAnnotation.type !== 'ArrayTypeAnnotation', + 'ArrayTypeAnnotations should have been processed earlier', + ); + + switch (structTypeAnnotation.type) { + case 'TypeAliasTypeAnnotation': { + /** + * TODO(T73943261): Support nullable object literals and aliases? + */ + return isStruct( + getNamespacedStructName(moduleName, structTypeAnnotation.name) + ' &', + ); + } + case 'ReservedFunctionValueTypeAnnotation': + switch (structTypeAnnotation.name) { + case 'RootTag': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + default: + (structTypeAnnotation.name: empty); + throw new Error( + `Unsupported type for param "${paramName}" in ${methodName}. Found: ${structTypeAnnotation.type}`, + ); + } + case 'StringTypeAnnotation': + return notStruct(wrapIntoNullableIfNeeded('NSString *')); + case 'NumberTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'FloatTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'DoubleTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'Int32TypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'BooleanTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'BOOL'); + case 'GenericObjectTypeAnnotation': + return notStruct(wrapIntoNullableIfNeeded('NSDictionary *')); + default: + (structTypeAnnotation.type: empty); + throw new Error( + `Unsupported type for param "${paramName}" in ${methodName}. Found: ${typeAnnotation.type}`, + ); + } +} + +function getReturnObjCType( + methodName: string, + typeAnnotation: NativeModuleReturnTypeAnnotation, +) { + function wrapIntoNullableIfNeeded(generatedType: string) { + return typeAnnotation.nullable + ? `${generatedType} _Nullable` + : generatedType; + } + + switch (typeAnnotation.type) { + case 'VoidTypeAnnotation': + return 'void'; + case 'PromiseTypeAnnotation': + return 'void'; + case 'ObjectTypeAnnotation': + return wrapIntoNullableIfNeeded('NSDictionary *'); + case 'TypeAliasTypeAnnotation': + return wrapIntoNullableIfNeeded('NSDictionary *'); + case 'ArrayTypeAnnotation': + if (typeAnnotation.elementType == null) { + return wrapIntoNullableIfNeeded('NSArray> *'); + } + + return wrapIntoNullableIfNeeded( + `NSArray<${getReturnObjCType( + methodName, + typeAnnotation.elementType, + )}> *`, + ); + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapIntoNullableIfNeeded('NSNumber *'); + default: + (typeAnnotation.name: empty); + throw new Error( + `Unsupported return type for ${methodName}. Found: ${typeAnnotation.name}`, + ); + } + case 'StringTypeAnnotation': + // TODO: Can NSString * returns not be _Nullable? + // In the legacy codegen, we don't surround NSSTring * with _Nullable + return wrapIntoNullableIfNeeded('NSString *'); + case 'NumberTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'FloatTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'DoubleTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'Int32TypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'BooleanTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'GenericObjectTypeAnnotation': + return wrapIntoNullableIfNeeded('NSDictionary *'); + default: + (typeAnnotation.type: empty); + throw new Error( + `Unsupported return type for ${methodName}. Found: ${typeAnnotation.type}`, + ); + } +} + +function getReturnJSType( + methodName: string, + typeAnnotation: NativeModuleReturnTypeAnnotation, +): ReturnJSType { + switch (typeAnnotation.type) { + case 'VoidTypeAnnotation': + return 'VoidKind'; + case 'PromiseTypeAnnotation': + return 'PromiseKind'; + case 'ObjectTypeAnnotation': + return 'ObjectKind'; + case 'TypeAliasTypeAnnotation': + return 'ObjectKind'; + case 'ArrayTypeAnnotation': + return 'ArrayKind'; + case 'ReservedFunctionValueTypeAnnotation': + return 'NumberKind'; + case 'StringTypeAnnotation': + return 'StringKind'; + case 'NumberTypeAnnotation': + return 'NumberKind'; + case 'FloatTypeAnnotation': + return 'NumberKind'; + case 'DoubleTypeAnnotation': + return 'NumberKind'; + case 'Int32TypeAnnotation': + return 'NumberKind'; + case 'BooleanTypeAnnotation': + return 'NumberKind'; + case 'GenericObjectTypeAnnotation': + return 'ObjectKind'; + default: + (typeAnnotation.type: empty); + throw new Error( + `Unsupported return type for ${methodName}. Found: ${typeAnnotation.type}`, + ); + } +} + +function serializeConstantsProtocolMethods( + moduleName: string, + property: NativeModulePropertySchema, + structCollector: StructCollector, + resolveAlias: AliasResolver, +): $ReadOnlyArray { + if (property.typeAnnotation.params.length !== 0) { + throw new Error( + `${moduleName}.getConstants() may only accept 0 arguments.`, + ); + } + + const {returnTypeAnnotation} = property.typeAnnotation; + if (returnTypeAnnotation.type !== 'ObjectTypeAnnotation') { + throw new Error( + `${moduleName}.getConstants() may only return an object literal: {|...|}.`, + ); + } + + if (returnTypeAnnotation.properties.length === 0) { + return []; + } + + const realTypeAnnotation = structCollector.process( + 'Constants', + 'CONSTANTS', + resolveAlias, + returnTypeAnnotation, + ); + + invariant( + realTypeAnnotation.type === 'TypeAliasTypeAnnotation', + "Unable to generate C++ struct from module's getConstants() method return type.", + ); + + const returnObjCType = `facebook::react::ModuleConstants`; + + return ['constantsToExport', 'getConstants'].map( + methodName => { + const protocolMethod = ProtocolMethodTemplate({ + methodName, + returnObjCType, + params: '', + }); + + return { + methodName: 'getConstants', + protocolMethod, + returnJSType: 'ObjectKind', + selector: 'getConstants', + structParamRecords: [], + }; + }, + ); +} + +module.exports = { + serializeMethod, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js new file mode 100644 index 00000000000000..82c69359a06d36 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js @@ -0,0 +1,125 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + */ + +'use strict'; + +import type {Struct} from '../StructCollector'; +import type { + MethodSerializationOutput, + StructParameterRecord, +} from '../serializeMethod'; + +const ModuleTemplate = ({ + moduleName, + structs, + methodSerializationOutputs, +}: $ReadOnly<{| + moduleName: string, + structs: $ReadOnlyArray, + methodSerializationOutputs: $ReadOnlyArray, +|}>) => ` +${structs + .map(struct => + RCTCxxConvertCategoryTemplate({moduleName, structName: struct.name}), + ) + .join('\n')} +namespace facebook { + namespace react { + ${methodSerializationOutputs + .map(serializedMethodParts => + InlineHostFunctionTemplate({ + moduleName, + methodName: serializedMethodParts.methodName, + returnJSType: serializedMethodParts.returnJSType, + selector: serializedMethodParts.selector, + }), + ) + .join('\n')} + + Native${moduleName}SpecJSI::Native${moduleName}SpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + ${methodSerializationOutputs + .map(({methodName, structParamRecords}) => + MethodMapEntryTemplate({ + moduleName, + methodName, + structParamRecords, + }), + ) + .join('\n' + ' '.repeat(8))} + } + } + } // namespace react +} // namespace facebook +`; + +const RCTCxxConvertCategoryTemplate = ({ + moduleName, + structName, +}: $ReadOnly<{| + moduleName: string, + structName: string, +|}>) => ` +@implementation RCTCxxConvert (Native${moduleName}_${structName}) ++ (RCTManagedPointer *)JS_Native${moduleName}_${structName}:(id)json +{ + return facebook::react::managedPointer(json); +} +@end +`; + +const InlineHostFunctionTemplate = ({ + moduleName, + methodName, + returnJSType, + selector, +}: $ReadOnly<{| + moduleName: string, + methodName: string, + returnJSType: string, + selector: string, +|}>) => ` + static facebook::jsi::Value __hostFunction_Native${moduleName}SpecJSI::${methodName}(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ${returnJSType}, "${methodName}", ${selector}, args, count); + } +`; + +const MethodMapEntryTemplate = ({ + moduleName, + methodName, + structParamRecords, +}: $ReadOnly<{| + moduleName: string, + methodName: string, + structParamRecords: $ReadOnlyArray, +|}>) => ` + methodMap_["${methodName}"] = MethodMetadata {1, __hostFunction_Native${moduleName}SpecJSI_${methodName}}; + ${structParamRecords + .map(({paramIndex, structName}) => { + return `setMethodArgConversionSelector(@"${methodName}", ${paramIndex}, @"JS_Native${moduleName}_${structName}:");`; + }) + .join('\n' + ' '.repeat(8))} +`; + +function serializeModuleSource( + moduleName: string, + structs: $ReadOnlyArray, + methodSerializationOutputs: $ReadOnlyArray, +): string { + return ModuleTemplate({ + moduleName, + structs, + methodSerializationOutputs, + }); +} + +module.exports = { + serializeModuleSource, +}; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js deleted file mode 100644 index c9e1d817a296d1..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js +++ /dev/null @@ -1,452 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict - * @format - */ - -'use strict'; - -import type { - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../../CodegenSchema'; -const { - flatObjects, - capitalizeFirstLetter, - getSafePropertyName, -} = require('./Utils'); -const {getTypeAliasTypeAnnotation} = require('../Utils'); -const {generateStructsForConstants} = require('./GenerateStructsForConstants'); - -const template = ` -::_CONSTANTS_::::_STRUCTS_::::_INLINES_:: -`; - -const structTemplate = ` -namespace JS { - namespace Native::_MODULE_NAME_:: { - struct ::_STRUCT_NAME_:: { - ::_STRUCT_PROPERTIES_:: - - ::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (Native::_MODULE_NAME_::_::_STRUCT_NAME_::) -+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_STRUCT_NAME_:::(id)json; -@end -`; - -const inlineTemplate = ` -inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const -{ - id const p = _v[@"::_PROPERTY_NAME_::"]; - return ::_RETURN_VALUE_::; -} -`; - -function getNamespacedStructName(structName: string): string { - return `JS::Native::_MODULE_NAME_::::${structName}`; -} - -function getElementTypeForArray( - property: ObjectParamTypeAnnotation, - name: string, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - - // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - if (typeAnnotation.type !== 'ArrayTypeAnnotation') { - throw new Error( - `Cannot get array element type for non-array type ${typeAnnotation.type}`, - ); - } - - if (!typeAnnotation.elementType) { - return 'id'; - } - - const type = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases) - .type - : typeAnnotation.elementType.type; - switch (type) { - case 'StringTypeAnnotation': - return 'NSString *'; - case 'DoubleTypeAnnotation': - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return 'double'; - case 'ObjectTypeAnnotation': - const structName = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? typeAnnotation.elementType.name - : `${property.name}Element`; - return getNamespacedStructName(structName); - case 'GenericObjectTypeAnnotation': - // TODO(T67565166): Generic objects are not type safe and should be disallowed in the schema. This case should throw an error once it is disallowed in schema. - console.error( - `Warning: Generic objects are not type safe and should be avoided whenever possible (see '${property.name}' in ${moduleName}'s ${name})`, - ); - return 'id'; - case 'BooleanTypeAnnotation': - case 'AnyObjectTypeAnnotation': - case 'AnyTypeAnnotation': - case 'ArrayTypeAnnotation': - case 'FunctionTypeAnnotation': - case 'ReservedFunctionValueTypeAnnotation': - case 'ReservedPropTypeAnnotation': - case 'StringEnumTypeAnnotation': - throw new Error(`Unsupported array element type, found: ${type}"`); - default: - (type: empty); - throw new Error(`Unknown array element type, found: ${type}"`); - } -} - -function getInlineMethodSignature( - property: ObjectParamTypeAnnotation, - name: string, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - function markOptionalTypeIfNecessary(type: string) { - if (property.optional) { - return `folly::Optional<${type}>`; - } - return type; - } - - // TODO(T67672788): Workaround for values key in NativeLinking which lacks a typeAnnotation. id is not type safe! - if (!typeAnnotation) { - console.error( - `Warning: Unsafe type found (see '${property.name}' in ${moduleName}'s ${name})`, - ); - return `id ${getSafePropertyName(property)}() const;`; - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - - const variableName = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? `${capitalizeFirstLetter(typeAnnotation.name)}` - : `${capitalizeFirstLetter(name)}${capitalizeFirstLetter( - getSafePropertyName(property), - )}`; - - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return `double ${getSafePropertyName(property)}() const;`; - default: - (realTypeAnnotation.name: empty); - throw new Error( - `Unknown prop type, found: ${realTypeAnnotation.name}"`, - ); - } - case 'StringTypeAnnotation': - return `NSString *${getSafePropertyName(property)}() const;`; - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return `${markOptionalTypeIfNecessary('double')} ${getSafePropertyName( - property, - )}() const;`; - case 'BooleanTypeAnnotation': - return `${markOptionalTypeIfNecessary('bool')} ${getSafePropertyName( - property, - )}() const;`; - case 'ObjectTypeAnnotation': - return `${markOptionalTypeIfNecessary( - getNamespacedStructName(variableName), - )} ${getSafePropertyName(property)}() const;`; - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - return `id ${ - property.optional ? '_Nullable ' : ' ' - }${getSafePropertyName(property)}() const;`; - case 'ArrayTypeAnnotation': - return `${markOptionalTypeIfNecessary( - `facebook::react::LazyVector<${getElementTypeForArray( - property, - name, - moduleName, - aliases, - )}>`, - )} ${getSafePropertyName(property)}() const;`; - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); - } -} - -function getInlineMethodImplementation( - property: ObjectParamTypeAnnotation, - name: string, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - function markOptionalTypeIfNecessary(type: string): string { - if (property.optional) { - return `folly::Optional<${type}> `; - } - return `${type} `; - } - function markOptionalValueIfNecessary(value: string): string { - if (property.optional) { - return `RCTBridgingToOptional${capitalizeFirstLetter(value)}`; - } - return `RCTBridgingTo${capitalizeFirstLetter(value)}`; - } - function bridgeArrayElementValueIfNecessary(element: string): string { - // TODO(T67898313): Workaround for NativeLinking's use of union type - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - if (typeAnnotation.type !== 'ArrayTypeAnnotation') { - throw new Error( - `Cannot get array element type for non-array type ${typeAnnotation.type}`, - ); - } - - if (!typeAnnotation.elementType) { - throw new Error(`Cannot get array element type for ${name}`); - } - - const type = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases) - .type - : typeAnnotation.elementType.type; - - switch (type) { - case 'StringTypeAnnotation': - return `RCTBridgingToString(${element})`; - case 'DoubleTypeAnnotation': - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return `RCTBridgingToDouble(${element})`; - case 'BooleanTypeAnnotation': - return `RCTBridgingToBool(${element})`; - case 'ObjectTypeAnnotation': - const structName = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? `${typeAnnotation.elementType.name}(${element})` - : `${getSafePropertyName(property)}Element(${element})`; - return getNamespacedStructName(structName); - case 'GenericObjectTypeAnnotation': - return element; - case 'AnyObjectTypeAnnotation': - case 'AnyTypeAnnotation': - case 'ArrayTypeAnnotation': - case 'FunctionTypeAnnotation': - case 'ReservedFunctionValueTypeAnnotation': - case 'ReservedPropTypeAnnotation': - case 'StringEnumTypeAnnotation': - case 'TupleTypeAnnotation': - throw new Error(`Unsupported array element type, found: ${type}"`); - default: - (type: empty); - throw new Error(`Unknown array element type, found: ${type}"`); - } - } - - // TODO(T67672788): Workaround for values key in NativeLinking which lacks a typeAnnotation. id is not type safe! - if (!typeAnnotation) { - console.error( - `Warning: Unsafe type found (see '${property.name}' in ${moduleName}'s ${name})`, - ); - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - property.optional ? 'id _Nullable ' : 'id ', - ) - .replace(/::_RETURN_VALUE_::/, 'p'); - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'double ') - .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToDouble(p)'); - default: - (realTypeAnnotation.name: empty); - throw new Error( - `Unknown prop type, found: ${realTypeAnnotation.name}"`, - ); - } - case 'StringTypeAnnotation': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'NSString *') - .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToString(p)'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, markOptionalTypeIfNecessary('double')) - .replace( - /::_RETURN_VALUE_::/, - `${markOptionalValueIfNecessary('double')}(p)`, - ); - case 'BooleanTypeAnnotation': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, markOptionalTypeIfNecessary('bool')) - .replace( - /::_RETURN_VALUE_::/, - `${markOptionalValueIfNecessary('bool')}(p)`, - ); - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - property.optional ? 'id _Nullable ' : 'id ', - ) - .replace(/::_RETURN_VALUE_::/, 'p'); - case 'ObjectTypeAnnotation': - const structName = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? `${capitalizeFirstLetter(typeAnnotation.name)}` - : `${name}${capitalizeFirstLetter(getSafePropertyName(property))}`; - const namespacedStructName = getNamespacedStructName(structName); - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - markOptionalTypeIfNecessary(namespacedStructName), - ) - .replace( - /::_RETURN_VALUE_::/, - property.optional - ? `(p == nil ? folly::none : folly::make_optional(${namespacedStructName}(p)))` - : `${namespacedStructName}(p)`, - ); - case 'ArrayTypeAnnotation': - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - markOptionalTypeIfNecessary( - `facebook::react::LazyVector<${getElementTypeForArray( - property, - name, - moduleName, - aliases, - )}>`, - ), - ) - .replace( - /::_RETURN_VALUE_::/, - `${markOptionalValueIfNecessary('vec')}(p, ^${getElementTypeForArray( - property, - name, - moduleName, - aliases, - )}(id itemValue_0) { return ${bridgeArrayElementValueIfNecessary( - 'itemValue_0', - )}; })`, - ); - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); - } -} - -function translateObjectsForStructs( - annotations: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, - >, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const flattenObjects = flatObjects(annotations, false, aliases); - - const translatedInlineMethods = flattenObjects - .reduce( - (acc, object) => - acc.concat( - object.properties.map(property => - getInlineMethodImplementation( - property, - object.name, - moduleName, - aliases, - ) - .replace(/::_PROPERTY_NAME_::/g, getSafePropertyName(property)) - .replace(/::_STRUCT_NAME_::/g, object.name), - ), - ), - [], - ) - .join('\n'); - - const translatedStructs = flattenObjects - .map(object => { - return structTemplate - .replace( - /::_STRUCT_PROPERTIES_::/g, - object.properties - .map(property => - getInlineMethodSignature( - property, - object.name, - moduleName, - aliases, - ), - ) - .join('\n '), - ) - .replace(/::_STRUCT_NAME_::/g, object.name); - }) - .reverse() - .join('\n'); - const translatedConstants = generateStructsForConstants(annotations, aliases); - - return template - .replace(/::_STRUCTS_::/, translatedStructs) - .replace(/::_INLINES_::/, translatedInlineMethods) - .replace(/::_CONSTANTS_::/, translatedConstants); -} -module.exports = { - translateObjectsForStructs, - capitalizeFirstLetter, - getNamespacedStructName, -}; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js deleted file mode 100644 index 0433152f7f627d..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js +++ /dev/null @@ -1,275 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict - * @format - */ - -'use strict'; - -import type { - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../../CodegenSchema'; -const {flatObjects, capitalizeFirstLetter} = require('./Utils'); -const {getTypeAliasTypeAnnotation} = require('../Utils'); - -const structTemplate = ` -namespace JS { - namespace Native::_MODULE_NAME_:: { - struct ::_STRUCT_NAME_:: { - - struct Builder { - struct Input { - ::_INPUT_:: - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing ::_STRUCT_NAME_:: */ - Builder(::_STRUCT_NAME_:: i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static ::_STRUCT_NAME_:: fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - ::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - ::_PROPERTIES_:: - return d; -}) {} -inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(::_STRUCT_NAME_:: i) : _factory(^{ - return i.unsafeRawValue(); -}) {}`; - -function getBuilderInputFieldDeclaration( - property: ObjectParamTypeAnnotation, - name: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - function markRequiredIfNecessary(annotation) { - if (!property.optional) { - return 'RCTRequired<' + annotation + '> ' + property.name + ';'; - } - return 'folly::Optional<' + annotation + '> ' + property.name + ';'; - } - const {typeAnnotation} = property; - - // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - - const variableName = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? typeAnnotation.name - : `${name}${capitalizeFirstLetter(property.name)}`; - - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return markRequiredIfNecessary('double'); - default: - (realTypeAnnotation.name: empty); - throw new Error( - `Unknown prop type, found: ${realTypeAnnotation.name}"`, - ); - } - case 'StringTypeAnnotation': - if (property.optional) { - return 'NSString *' + property.name + ';'; - } - return markRequiredIfNecessary('NSString *'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return markRequiredIfNecessary('double'); - case 'BooleanTypeAnnotation': - return markRequiredIfNecessary('bool'); - case 'ObjectTypeAnnotation': - return markRequiredIfNecessary( - `JS::Native::_MODULE_NAME_::::${variableName}::Builder`, - ); - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - if (property.optional) { - return 'id _Nullable ' + property.name + ';'; - } - return markRequiredIfNecessary('id'); - case 'ArrayTypeAnnotation': - return markRequiredIfNecessary('std::vector>'); - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); - } -} - -function safeGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${name}; - `.trim(); -} - -function arrayGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = RCTConvert${ - optional ? 'Optional' : '' - }VecToArray(${name}, ^id(id el_) { return el_; }); - `.trim(); -} - -function boolGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${ - optional - ? `${name}.hasValue() ? @((BOOL)${name}.value()) : nil` - : `@(${name})` - }; - `.trim(); -} - -function numberGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${ - optional - ? `${name}.hasValue() ? @((double)${name}.value()) : nil` - : `@(${name})` - }; - `.trim(); -} - -function unsafeGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${ - optional - ? `${name}.hasValue() ? ${name}.value().buildUnsafeRawValue() : nil` - : `${name}.buildUnsafeRawValue()` - }; - `.trim(); -} - -function getObjectProperty( - property: ObjectParamTypeAnnotation, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - - // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - const type = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases).type - : typeAnnotation.type; - - switch (type) { - case 'ReservedFunctionValueTypeAnnotation': - if (typeAnnotation.name == null) { - throw new Error(`Prop type ${type} has no name.`); - } - switch (typeAnnotation.name) { - case 'RootTag': - return numberGetter(property.name, property.optional); - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.name: empty); - throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); - } - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return numberGetter(property.name, property.optional); - case 'BooleanTypeAnnotation': - return boolGetter(property.name, property.optional); - case 'StringTypeAnnotation': - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - return safeGetter(property.name, property.optional); - case 'ObjectTypeAnnotation': - return unsafeGetter(property.name, property.optional); - case 'ArrayTypeAnnotation': - return arrayGetter(property.name, property.optional); - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${type}"`); - } -} - -function generateStructsForConstants( - annotations: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, - >, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - return flatObjects(annotations, true, aliases) - .reduce( - (acc, object) => - acc.concat( - structTemplate - .replace( - /::_INPUT_::/g, - object.properties - .map(property => - getBuilderInputFieldDeclaration( - property, - object.name, - aliases, - ), - ) - .join('\n '), - ) - .replace( - /::_PROPERTIES_::/g, - object.properties - .map(property => getObjectProperty(property, aliases)) - .join('\n'), - ) - .replace(/::_STRUCT_NAME_::/g, object.name), - ), - [], - ) - .reverse() - .join('\n') - .replace(/SpecGetConstantsReturnType/g, 'Constants') - .replace(/GetConstantsReturnType/g, 'Constants'); -} -module.exports = { - generateStructsForConstants, - capitalizeFirstLetter, -}; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js deleted file mode 100644 index fd4dca38468dad..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict - * @format - */ - -'use strict'; - -import type { - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../../CodegenSchema'; -const {getTypeAliasTypeAnnotation} = require('../Utils'); - -function capitalizeFirstLetter(string: string): string { - return string.charAt(0).toUpperCase() + string.slice(1); -} - -function flatObjects( - annotations: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, - >, - forConstants: boolean = false, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): $ReadOnlyArray< - $ReadOnly<{| - name: string, - properties: $ReadOnlyArray, - |}>, -> { - let objectTypesToFlatten: Array<{| - properties: $ReadOnlyArray, - name: string, - |}> = annotations - .map(annotation => { - if (annotation.object.type === 'TypeAliasTypeAnnotation') { - const alias = getTypeAliasTypeAnnotation(annotation.name, aliases); - return {name: annotation.name, properties: alias.properties}; - } - return { - name: annotation.name, - properties: annotation.object.properties, - }; - }) - .filter( - annotation => - (annotation.name === 'SpecGetConstantsReturnType') === forConstants, - ) - .filter( - annotation => - annotation.name !== 'SpecGetConstantsReturnType' || - annotation.properties.length > 0, - ); - - let flattenObjects: Array<{| - properties: $ReadOnlyArray, - name: string, - |}> = []; - - while (objectTypesToFlatten.length !== 0) { - const oldObjectTypesToFlatten = objectTypesToFlatten; - objectTypesToFlatten = []; - flattenObjects = flattenObjects.concat( - oldObjectTypesToFlatten.map(object => { - const {properties} = object; - if (properties !== undefined) { - objectTypesToFlatten = objectTypesToFlatten.concat( - properties.reduce((acc, curr) => { - if ( - curr.typeAnnotation && - curr.typeAnnotation.type === 'ObjectTypeAnnotation' && - curr.typeAnnotation.properties - ) { - return acc.concat({ - properties: curr.typeAnnotation.properties, - name: object.name + capitalizeFirstLetter(curr.name), - }); - } - return acc; - }, []), - ); - } - return object; - }), - ); - } - - return flattenObjects; -} - -function getSafePropertyName(property: ObjectParamTypeAnnotation): string { - if (property.name === 'id') { - return `${property.name}_`; - } - return property.name; -} - -module.exports = { - flatObjects, - capitalizeFirstLetter, - getSafePropertyName, -}; diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js deleted file mode 100644 index 2de452b87c2c39..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema.js'; -const SIMPLE_STRUCT: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, -> = [ - { - name: 'SpecSampleFuncReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'a', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'b', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'c', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - { - optional: false, - name: 'd', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'e', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'f', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'g', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'h', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'i', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'j', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - ], - }, - }, - ], - }, - }, - { - optional: false, - name: 'k', - typeAnnotation: { - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }, - }, - ], - }, - }, -]; - -const SIMPLE_CONSTANTS: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, -> = [ - { - name: 'SpecGetConstantsReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'a', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'b', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'c', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - { - optional: false, - name: 'd', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'e', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'f', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'g', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'h', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'i', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'j', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - ], - }, - }, - ], - }, - }, - { - optional: false, - name: 'k', - typeAnnotation: { - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }, - }, - ], - }, - }, -]; -module.exports = { - SIMPLE_STRUCT, - SIMPLE_CONSTANTS, -}; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js index b41441cb2daf7c..3c4943971857b0 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js @@ -12,7 +12,7 @@ 'use strict'; const fixtures = require('../__test_fixtures__/fixtures.js'); -const generator = require('../GenerateModuleHObjCpp.js'); +const generator = require('../GenerateModuleObjCpp'); describe('GenerateModuleHObjCpp', () => { Object.keys(fixtures) @@ -21,8 +21,9 @@ describe('GenerateModuleHObjCpp', () => { const fixture = fixtures[fixtureName]; it(`can generate fixture ${fixtureName}`, () => { + const output = generator.generate(fixtureName, fixture, 'SampleSpec'); expect( - generator.generate(fixtureName, fixture, 'SampleSpec'), + new Map([['SampleSpec.h', output.get('SampleSpec.h')]]), ).toMatchSnapshot(); }); }); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js index 5bfd8c79e07682..ec8f4842a106bf 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js @@ -12,7 +12,7 @@ 'use strict'; const fixtures = require('../__test_fixtures__/fixtures.js'); -const generator = require('../GenerateModuleMm.js'); +const generator = require('../GenerateModuleObjCpp'); describe('GenerateModuleMm', () => { Object.keys(fixtures) @@ -21,8 +21,11 @@ describe('GenerateModuleMm', () => { const fixture = fixtures[fixtureName]; it(`can generate fixture ${fixtureName}`, () => { + const output = generator.generate(fixtureName, fixture, 'SampleSpec'); expect( - generator.generate(fixtureName, fixture, 'SampleSpec'), + new Map([ + ['SampleSpec-generated.mm', output.get('SampleSpec-generated.mm')], + ]), ).toMatchSnapshot(); }); }); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js deleted file mode 100644 index a66b5ff7e4c28c..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @emails oncall+react_native - * @flow strict-local - * @format - */ - -'use strict'; - -const fixtures = require('../__test_fixtures__/structFixtures.js'); -const generator = require('../ObjCppUtils/GenerateStructs.js'); - -describe('GenerateStructs', () => { - Object.keys(fixtures) - .sort() - .forEach(fixtureName => { - const fixture = fixtures[fixtureName]; - - it(`can generate fixture ${fixtureName}`, () => { - expect( - generator - .translateObjectsForStructs(fixture, fixtureName, {}) - .replace(/::_MODULE_NAME_::/g, 'SampleTurboModule'), - ).toMatchSnapshot(); - }); - }); -}); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap index 939b9bcea8d2f2..2d7f078c5257b9 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap @@ -34,24 +34,6 @@ Map { -namespace JS { - namespace NativeSampleTurboModule { - struct SpecOptionalsAOptionalObjectProperty { - double x() const; - double y() const; - - SpecOptionalsAOptionalObjectProperty(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json; -@end - - namespace JS { namespace NativeSampleTurboModule { struct SpecDifficultAE { @@ -74,57 +56,38 @@ namespace JS { namespace JS { namespace NativeSampleTurboModule { - struct SpecGetArraysOptionsArrayOfObjectsElement { - double numberProperty() const; - - SpecGetArraysOptionsArrayOfObjectsElement(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement:(id)json; -@end - - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecGetArraysOptions { - facebook::react::LazyVector arrayOfNumbers() const; - folly::Optional> optionalArrayOfNumbers() const; - facebook::react::LazyVector arrayOfStrings() const; - folly::Optional> optionalArrayOfStrings() const; - facebook::react::LazyVector arrayOfObjects() const; + struct SpecDifficultA { + bool D() const; + JS::NativeSampleTurboModule::SpecDifficultAE E() const; + NSString *F() const; - SpecGetArraysOptions(NSDictionary *const v) : _v(v) {} + SpecDifficultA(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptions) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptions:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultA:(id)json; @end namespace JS { namespace NativeSampleTurboModule { - struct SpecOptionalMethodExtrasElement { - NSString *key() const; - id value() const; + struct SpecOptionalsAOptionalObjectProperty { + double x() const; + double y() const; - SpecOptionalMethodExtrasElement(NSDictionary *const v) : _v(v) {} + SpecOptionalsAOptionalObjectProperty(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalMethodExtrasElement) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalMethodExtrasElement:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json; @end @@ -151,83 +114,128 @@ namespace JS { namespace JS { namespace NativeSampleTurboModule { - struct SpecDifficultReturnType { - bool D() const; - double E() const; - NSString *F() const; + struct SpecGetArraysOptionsArrayOfObjectsElement { + double numberProperty() const; - SpecDifficultReturnType(NSDictionary *const v) : _v(v) {} + SpecGetArraysOptionsArrayOfObjectsElement(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultReturnType) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultReturnType:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement:(id)json; @end namespace JS { namespace NativeSampleTurboModule { - struct SpecDifficultA { - bool D() const; - JS::NativeSampleTurboModule::SpecDifficultAE E() const; - NSString *F() const; + struct SpecGetArraysOptions { + facebook::react::LazyVector arrayOfNumbers() const; + folly::Optional> optionalArrayOfNumbers() const; + facebook::react::LazyVector arrayOfStrings() const; + folly::Optional> optionalArrayOfStrings() const; + facebook::react::LazyVector arrayOfObjects() const; - SpecDifficultA(NSDictionary *const v) : _v(v) {} + SpecGetArraysOptions(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultA) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultA:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptions) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptions:(id)json; @end -inline bool JS::NativeSampleTurboModule::SpecDifficultA::D() const +@protocol NativeSampleTurboModuleSpec + +- (NSDictionary *)difficult:(JS::NativeSampleTurboModule::SpecDifficultA &)A; +- (void)optionals:(JS::NativeSampleTurboModule::SpecOptionalsA &)A; +- (void)optionalMethod:(NSDictionary *)options + callback:(RCTResponseSenderBlock)callback + extras:(NSArray *)extras; +- (void)getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions &)options; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +inline bool JS::NativeSampleTurboModule::SpecDifficultAE::D() const { id const p = _v[@\\"D\\"]; return RCTBridgingToBool(p); } -inline JS::NativeSampleTurboModule::SpecDifficultAE JS::NativeSampleTurboModule::SpecDifficultA::E() const +inline double JS::NativeSampleTurboModule::SpecDifficultAE::E() const { id const p = _v[@\\"E\\"]; - return JS::NativeSampleTurboModule::SpecDifficultAE(p); + return RCTBridgingToDouble(p); } -inline NSString *JS::NativeSampleTurboModule::SpecDifficultA::F() const +inline NSString *JS::NativeSampleTurboModule::SpecDifficultAE::F() const { id const p = _v[@\\"F\\"]; return RCTBridgingToString(p); } -inline bool JS::NativeSampleTurboModule::SpecDifficultReturnType::D() const +inline double JS::NativeSampleTurboModule::SpecDifficultAE::id_() const +{ + id const p = _v[@\\"id_\\"]; + return RCTBridgingToDouble(p); +} + + +inline bool JS::NativeSampleTurboModule::SpecDifficultA::D() const { id const p = _v[@\\"D\\"]; return RCTBridgingToBool(p); } -inline double JS::NativeSampleTurboModule::SpecDifficultReturnType::E() const +inline JS::NativeSampleTurboModule::SpecDifficultAE JS::NativeSampleTurboModule::SpecDifficultA::E() const { id const p = _v[@\\"E\\"]; - return RCTBridgingToDouble(p); + return JS::NativeSampleTurboModule::SpecDifficultAE(p); } -inline NSString *JS::NativeSampleTurboModule::SpecDifficultReturnType::F() const +inline NSString *JS::NativeSampleTurboModule::SpecDifficultA::F() const { id const p = _v[@\\"F\\"]; return RCTBridgingToString(p); } +inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::x() const +{ + id const p = _v[@\\"x\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::y() const +{ + id const p = _v[@\\"y\\"]; + return RCTBridgingToDouble(p); +} + + inline folly::Optional JS::NativeSampleTurboModule::SpecOptionalsA::optionalNumberProperty() const { id const p = _v[@\\"optionalNumberProperty\\"]; @@ -263,17 +271,10 @@ inline folly::Optional JS::NativeSampleTurboModule::SpecOptionalsA::option } -inline NSString *JS::NativeSampleTurboModule::SpecOptionalMethodExtrasElement::key() const -{ - id const p = _v[@\\"key\\"]; - return RCTBridgingToString(p); -} - - -inline id JS::NativeSampleTurboModule::SpecOptionalMethodExtrasElement::value() const +inline double JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement::numberProperty() const { - id const p = _v[@\\"value\\"]; - return p; + id const p = _v[@\\"numberProperty\\"]; + return RCTBridgingToDouble(p); } @@ -305,84 +306,12 @@ inline folly::Optional> JS::NativeSample } -inline facebook::react::LazyVector JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const +inline facebook::react::LazyVector JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const { id const p = _v[@\\"arrayOfObjects\\"]; - return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::arrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::arrayOfObjectsElement(itemValue_0); }); -} - - -inline double JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement::numberProperty() const -{ - id const p = _v[@\\"numberProperty\\"]; - return RCTBridgingToDouble(p); -} - - -inline bool JS::NativeSampleTurboModule::SpecDifficultAE::D() const -{ - id const p = _v[@\\"D\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecDifficultAE::E() const -{ - id const p = _v[@\\"E\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeSampleTurboModule::SpecDifficultAE::F() const -{ - id const p = _v[@\\"F\\"]; - return RCTBridgingToString(p); -} - - -inline double JS::NativeSampleTurboModule::SpecDifficultAE::id_() const -{ - id const p = _v[@\\"id_\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::x() const -{ - id const p = _v[@\\"x\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::y() const -{ - id const p = _v[@\\"y\\"]; - return RCTBridgingToDouble(p); + return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(p); }); } - - -@protocol NativeSampleTurboModuleSpec -- (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA &)A; -- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA &)A; -- (void) optionalMethod:(NSDictionary *)options - callback:(RCTResponseSenderBlock)callback - extras:(NSArray * _Nullable)extras; -- (void) getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions &)options; -@end - - -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'SampleTurboModule' - */ - class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - } // namespace react -} // namespace facebook ", } `; @@ -421,24 +350,25 @@ Map { - - @protocol NativeSampleTurboModuleSpec -@end +@end namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ + * ObjC++ class for module 'SampleTurboModule' + */ class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { public: NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react } // namespace facebook + + + ", } `; @@ -479,19 +409,19 @@ Map { namespace JS { namespace NativeAliasTurboModule { - struct OptionsDisplaySize { - double width() const; - double height() const; + struct OptionsOffset { + double x() const; + double y() const; - OptionsDisplaySize(NSDictionary *const v) : _v(v) {} + OptionsOffset(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize) -+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json; +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json; @end @@ -515,19 +445,19 @@ namespace JS { namespace JS { namespace NativeAliasTurboModule { - struct OptionsOffset { - double x() const; - double y() const; + struct OptionsDisplaySize { + double width() const; + double height() const; - OptionsOffset(NSDictionary *const v) : _v(v) {} + OptionsDisplaySize(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) -+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json; +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json; @end @@ -551,40 +481,24 @@ namespace JS { + (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json; @end -inline JS::NativeAliasTurboModule::OptionsOffset JS::NativeAliasTurboModule::Options::offset() const -{ - id const p = _v[@\\"offset\\"]; - return JS::NativeAliasTurboModule::OptionsOffset(p); -} +@protocol NativeAliasTurboModuleSpec +- (void)cropImage:(JS::NativeAliasTurboModule::Options &)cropData; -inline JS::NativeAliasTurboModule::OptionsSize JS::NativeAliasTurboModule::Options::size() const -{ - id const p = _v[@\\"size\\"]; - return JS::NativeAliasTurboModule::OptionsSize(p); -} +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'AliasTurboModule' + */ + class JSI_EXPORT NativeAliasTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook -inline folly::Optional JS::NativeAliasTurboModule::Options::displaySize() const -{ - id const p = _v[@\\"displaySize\\"]; - return (p == nil ? folly::none : folly::make_optional(JS::NativeAliasTurboModule::OptionsDisplaySize(p))); -} - - -inline NSString *JS::NativeAliasTurboModule::Options::resizeMode() const -{ - id const p = _v[@\\"resizeMode\\"]; - return RCTBridgingToString(p); -} - - -inline folly::Optional JS::NativeAliasTurboModule::Options::allowExternalStorage() const -{ - id const p = _v[@\\"allowExternalStorage\\"]; - return RCTBridgingToOptionalBool(p); -} - inline double JS::NativeAliasTurboModule::OptionsOffset::x() const { @@ -628,24 +542,40 @@ inline double JS::NativeAliasTurboModule::OptionsDisplaySize::height() const } +inline JS::NativeAliasTurboModule::OptionsOffset JS::NativeAliasTurboModule::Options::offset() const +{ + id const p = _v[@\\"offset\\"]; + return JS::NativeAliasTurboModule::OptionsOffset(p); +} -@protocol NativeAliasTurboModuleSpec -- (void) cropImage:(JS::NativeAliasTurboModule::Options &)cropData; -@end +inline JS::NativeAliasTurboModule::OptionsSize JS::NativeAliasTurboModule::Options::size() const +{ + id const p = _v[@\\"size\\"]; + return JS::NativeAliasTurboModule::OptionsSize(p); +} -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'AliasTurboModule' - */ - class JSI_EXPORT NativeAliasTurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - } // namespace react -} // namespace facebook +inline folly::Optional JS::NativeAliasTurboModule::Options::displaySize() const +{ + id const p = _v[@\\"displaySize\\"]; + return (p == nil ? folly::none : folly::make_optional(JS::NativeAliasTurboModule::OptionsDisplaySize(p))); +} + + +inline NSString *JS::NativeAliasTurboModule::Options::resizeMode() const +{ + id const p = _v[@\\"resizeMode\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline folly::Optional JS::NativeAliasTurboModule::Options::allowExternalStorage() const +{ + id const p = _v[@\\"allowExternalStorage\\"]; + return RCTBridgingToOptionalBool(p); +} + ", } `; @@ -686,143 +616,164 @@ Map { namespace JS { namespace NativeCameraRollManager { - struct PhotoIdentifierNodeLocation { - double longitude() const; - double latitude() const; - folly::Optional altitude() const; - folly::Optional heading() const; - folly::Optional speed() const; - - PhotoIdentifierNodeLocation(NSDictionary *const v) : _v(v) {} + struct GetPhotosParams { + double first() const; + NSString *after() const; + NSString *groupName() const; + NSString *groupTypes() const; + NSString *assetType() const; + folly::Optional maxSize() const; + folly::Optional> mimeTypes() const; + + GetPhotosParams(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json; +@interface RCTCxxConvert (NativeCameraRollManager_GetPhotosParams) ++ (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json; @end +@protocol NativeCameraRollManagerSpec -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifierNode { - JS::NativeCameraRollManager::PhotoIdentifierImage image() const; - NSString *type() const; - NSString *group_name() const; - double timestamp() const; - JS::NativeCameraRollManager::PhotoIdentifierNodeLocation location() const; - - PhotoIdentifierNode(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} +- (void)getPhotos:(JS::NativeCameraRollManager::GetPhotosParams &)params + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)saveToCameraRoll:(NSString *)uri + type:(NSString *)type + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)deletePhotos:(NSArray *)assets + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json; @end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'CameraRollManager' + */ + class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { + public: + NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifiersPagePage_info { - bool has_next_page() const; - NSString *start_cursor() const; - NSString *end_cursor() const; + namespace NativeExceptionsManager { + struct StackFrame { + folly::Optional column() const; + NSString *file() const; + folly::Optional lineNumber() const; + NSString *methodName() const; + folly::Optional collapse() const; - PhotoIdentifiersPagePage_info(NSDictionary *const v) : _v(v) {} + StackFrame(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json; +@interface RCTCxxConvert (NativeExceptionsManager_StackFrame) ++ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json; @end namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifierImage { - NSString *uri() const; - double playableDuration() const; - double width() const; - double height() const; - folly::Optional isStored() const; - NSString *filename() const; + namespace NativeExceptionsManager { + struct ExceptionData { + NSString *message() const; + NSString *originalMessage() const; + NSString *name() const; + NSString *componentStack() const; + facebook::react::LazyVector stack() const; + double id_() const; + bool isFatal() const; + id _Nullable extraData() const; - PhotoIdentifierImage(NSDictionary *const v) : _v(v) {} + ExceptionData(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json; +@interface RCTCxxConvert (NativeExceptionsManager_ExceptionData) ++ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json; @end +@protocol NativeExceptionsManagerSpec -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifier { - JS::NativeCameraRollManager::PhotoIdentifierNode node() const; +- (void)reportFatalException:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void)reportSoftException:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void)reportException:(JS::NativeExceptionsManager::ExceptionData &)data; +- (void)updateExceptionMessage:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void)dismissRedbox; - PhotoIdentifier(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ExceptionsManager' + */ + class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { + public: + NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; - } -} + } // namespace react +} // namespace facebook -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json; -@end namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifiersPage { - facebook::react::LazyVector edges() const; - JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info page_info() const; + namespace NativeImagePickerIOS { + struct SpecOpenCameraDialogConfig { + bool unmirrorFrontFacingCamera() const; + bool videoMode() const; - PhotoIdentifiersPage(NSDictionary *const v) : _v(v) {} + SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json; +@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) ++ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json; @end +@protocol NativeImagePickerIOSSpec -namespace JS { - namespace NativeCameraRollManager { - struct GetPhotosParams { - double first() const; - NSString *after() const; - NSString *groupName() const; - NSString *groupTypes() const; - NSString *assetType() const; - folly::Optional maxSize() const; - folly::Optional> mimeTypes() const; +- (void)openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config + successCallback:(RCTResponseSenderBlock)successCallback + cancelCallback:(RCTResponseSenderBlock)cancelCallback; - GetPhotosParams(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ImagePickerIOS' + */ + class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { + public: + NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; - } -} + } // namespace react +} // namespace facebook + -@interface RCTCxxConvert (NativeCameraRollManager_GetPhotosParams) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json; -@end inline double JS::NativeCameraRollManager::GetPhotosParams::first() const { @@ -834,28 +785,28 @@ inline double JS::NativeCameraRollManager::GetPhotosParams::first() const inline NSString *JS::NativeCameraRollManager::GetPhotosParams::after() const { id const p = _v[@\\"after\\"]; - return RCTBridgingToString(p); + return RCTBridgingToOptionalString(p); } inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupName() const { id const p = _v[@\\"groupName\\"]; - return RCTBridgingToString(p); + return RCTBridgingToOptionalString(p); } inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupTypes() const { id const p = _v[@\\"groupTypes\\"]; - return RCTBridgingToString(p); + return RCTBridgingToOptionalString(p); } inline NSString *JS::NativeCameraRollManager::GetPhotosParams::assetType() const { id const p = _v[@\\"assetType\\"]; - return RCTBridgingToString(p); + return RCTBridgingToOptionalString(p); } @@ -873,220 +824,40 @@ inline folly::Optional> JS::NativeCamera } -inline facebook::react::LazyVector JS::NativeCameraRollManager::PhotoIdentifiersPage::edges() const -{ - id const p = _v[@\\"edges\\"]; - return RCTBridgingToVec(p, ^JS::NativeCameraRollManager::PhotoIdentifier(id itemValue_0) { return JS::NativeCameraRollManager::PhotoIdentifier(itemValue_0); }); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info JS::NativeCameraRollManager::PhotoIdentifiersPage::page_info() const -{ - id const p = _v[@\\"page_info\\"]; - return JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info(p); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifierNode JS::NativeCameraRollManager::PhotoIdentifier::node() const -{ - id const p = _v[@\\"node\\"]; - return JS::NativeCameraRollManager::PhotoIdentifierNode(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::uri() const -{ - id const p = _v[@\\"uri\\"]; - return RCTBridgingToString(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierImage::playableDuration() const -{ - id const p = _v[@\\"playableDuration\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierImage::width() const -{ - id const p = _v[@\\"width\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierImage::height() const -{ - id const p = _v[@\\"height\\"]; - return RCTBridgingToDouble(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierImage::isStored() const -{ - id const p = _v[@\\"isStored\\"]; - return RCTBridgingToOptionalBool(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::filename() const -{ - id const p = _v[@\\"filename\\"]; - return RCTBridgingToString(p); -} - - -inline bool JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::has_next_page() const -{ - id const p = _v[@\\"has_next_page\\"]; - return RCTBridgingToBool(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::start_cursor() const -{ - id const p = _v[@\\"start_cursor\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::end_cursor() const -{ - id const p = _v[@\\"end_cursor\\"]; - return RCTBridgingToString(p); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifierImage JS::NativeCameraRollManager::PhotoIdentifierNode::image() const -{ - id const p = _v[@\\"image\\"]; - return JS::NativeCameraRollManager::PhotoIdentifierImage(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::type() const +inline folly::Optional JS::NativeExceptionsManager::StackFrame::column() const { - id const p = _v[@\\"type\\"]; - return RCTBridgingToString(p); + id const p = _v[@\\"column\\"]; + return RCTBridgingToOptionalDouble(p); } -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::group_name() const +inline NSString *JS::NativeExceptionsManager::StackFrame::file() const { - id const p = _v[@\\"group_name\\"]; + id const p = _v[@\\"file\\"]; return RCTBridgingToString(p); } -inline double JS::NativeCameraRollManager::PhotoIdentifierNode::timestamp() const -{ - id const p = _v[@\\"timestamp\\"]; - return RCTBridgingToDouble(p); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifierNodeLocation JS::NativeCameraRollManager::PhotoIdentifierNode::location() const -{ - id const p = _v[@\\"location\\"]; - return JS::NativeCameraRollManager::PhotoIdentifierNodeLocation(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::longitude() const -{ - id const p = _v[@\\"longitude\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::latitude() const -{ - id const p = _v[@\\"latitude\\"]; - return RCTBridgingToDouble(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::altitude() const +inline folly::Optional JS::NativeExceptionsManager::StackFrame::lineNumber() const { - id const p = _v[@\\"altitude\\"]; + id const p = _v[@\\"lineNumber\\"]; return RCTBridgingToOptionalDouble(p); } -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::heading() const +inline NSString *JS::NativeExceptionsManager::StackFrame::methodName() const { - id const p = _v[@\\"heading\\"]; - return RCTBridgingToOptionalDouble(p); + id const p = _v[@\\"methodName\\"]; + return RCTBridgingToString(p); } -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::speed() const +inline folly::Optional JS::NativeExceptionsManager::StackFrame::collapse() const { - id const p = _v[@\\"speed\\"]; - return RCTBridgingToOptionalDouble(p); -} - - - -@protocol NativeCameraRollManagerSpec - -- (void) getPhotos:(JS::NativeCameraRollManager::GetPhotosParams &)params - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; -- (void) saveToCameraRoll:(NSString *)uri - type:(NSString *)type - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; -- (void) deletePhotos:(NSArray *)assets - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; -@end - - - -namespace JS { - namespace NativeExceptionsManager { - struct StackFrame { - folly::Optional column() const; - NSString *file() const; - folly::Optional lineNumber() const; - NSString *methodName() const; - folly::Optional collapse() const; - - StackFrame(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeExceptionsManager_StackFrame) -+ (RCTManagedPointer *)JS_NativeExceptionsManager_StackFrame:(id)json; -@end - - -namespace JS { - namespace NativeExceptionsManager { - struct ExceptionData { - NSString *message() const; - NSString *originalMessage() const; - NSString *name() const; - NSString *componentStack() const; - facebook::react::LazyVector stack() const; - double id_() const; - bool isFatal() const; - id _Nullable extraData() const; - - ExceptionData(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } + id const p = _v[@\\"collapse\\"]; + return RCTBridgingToOptionalBool(p); } -@interface RCTCxxConvert (NativeExceptionsManager_ExceptionData) -+ (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json; -@end inline NSString *JS::NativeExceptionsManager::ExceptionData::message() const { @@ -1119,7 +890,7 @@ inline NSString *JS::NativeExceptionsManager::ExceptionData::componentStack() co inline facebook::react::LazyVector JS::NativeExceptionsManager::ExceptionData::stack() const { id const p = _v[@\\"stack\\"]; - return RCTBridgingToVec(p, ^JS::NativeExceptionsManager::StackFrame(id itemValue_0) { return JS::NativeExceptionsManager::StackFrame(itemValue_0); }); + return RCTBridgingToVec(p, ^JS::NativeExceptionsManager::StackFrame(id itemValue_0) { return JS::NativeExceptionsManager::StackFrame(p); }); } @@ -1144,75 +915,6 @@ inline id _Nullable JS::NativeExceptionsManager::ExceptionData::extraD } -inline folly::Optional JS::NativeExceptionsManager::StackFrame::column() const -{ - id const p = _v[@\\"column\\"]; - return RCTBridgingToOptionalDouble(p); -} - - -inline NSString *JS::NativeExceptionsManager::StackFrame::file() const -{ - id const p = _v[@\\"file\\"]; - return RCTBridgingToString(p); -} - - -inline folly::Optional JS::NativeExceptionsManager::StackFrame::lineNumber() const -{ - id const p = _v[@\\"lineNumber\\"]; - return RCTBridgingToOptionalDouble(p); -} - - -inline NSString *JS::NativeExceptionsManager::StackFrame::methodName() const -{ - id const p = _v[@\\"methodName\\"]; - return RCTBridgingToString(p); -} - - -inline folly::Optional JS::NativeExceptionsManager::StackFrame::collapse() const -{ - id const p = _v[@\\"collapse\\"]; - return RCTBridgingToOptionalBool(p); -} - - - -@protocol NativeExceptionsManagerSpec -- (void) reportFatalException:(NSString *)message - stack:(NSArray *)stack - exceptionId:(double)exceptionId; -- (void) reportSoftException:(NSString *)message - stack:(NSArray *)stack - exceptionId:(double)exceptionId; -- (void) reportException:(JS::NativeExceptionsManager::ExceptionData &)data; -- (void) updateExceptionMessage:(NSString *)message - stack:(NSArray *)stack - exceptionId:(double)exceptionId; -- (void) dismissRedbox; -@end - - - -namespace JS { - namespace NativeImagePickerIOS { - struct SpecOpenCameraDialogConfig { - bool unmirrorFrontFacingCamera() const; - bool videoMode() const; - - SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) -+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json; -@end - inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const { id const p = _v[@\\"unmirrorFrontFacingCamera\\"]; @@ -1226,40 +928,6 @@ inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::videoMode() co return RCTBridgingToBool(p); } - - -@protocol NativeImagePickerIOSSpec -- (void) openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config - successCallback:(RCTResponseSenderBlock)successCallback - cancelCallback:(RCTResponseSenderBlock)cancelCallback; -@end - - -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'CameraRollManager' - */ - class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { - public: - NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - /** - * ObjC++ class for module 'ExceptionsManager' - */ - class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { - public: - NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - /** - * ObjC++ class for module 'ImagePickerIOS' - */ - class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { - public: - NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - } // namespace react -} // namespace facebook ", } `; @@ -1327,53 +995,53 @@ namespace JS { }; } } - -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto const1 = i.const1.get(); - d[@\\"const1\\"] = @(const1); -auto const2 = i.const2.get(); - d[@\\"const2\\"] = @(const2); -auto const3 = i.const3.get(); - d[@\\"const3\\"] = const3; - return d; -}) {} -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ - return i.unsafeRawValue(); -}) {} - - @protocol NativeSampleTurboModuleSpec + +- (void)voidFunc; +- (NSNumber *)getBool:(BOOL)arg; +- (NSNumber *)getNumber:(double)arg; +- (NSString *)getString:(NSString *)arg; +- (NSArray *)getArray:(NSArray *)arg; +- (NSDictionary *)getObject:(NSDictionary *)arg; +- (NSNumber *)getRootTag:(double)arg; +- (NSDictionary *)getValue:(double)x + y:(NSString *)y + z:(NSDictionary *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(BOOL)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; - (facebook::react::ModuleConstants)constantsToExport; - (facebook::react::ModuleConstants)getConstants; -- (void) voidFunc; -- (BOOL) getBool:(BOOL)arg; -- (NSNumber *) getNumber:(double)arg; -- (NSString *) getString:(NSString *)arg; -- (NSArray> *) getArray:(NSArray *)arg; -- (NSDictionary *) getObject:(NSDictionary *)arg; -- (NSNumber *) getRootTag:(double)arg; -- (NSDictionary *) getValue:(double)x - y:(NSString *)y - z:(NSDictionary *)z; -- (void) getValueWithCallback:(RCTResponseSenderBlock)callback; -- (void) getValueWithPromise:(BOOL)error - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; -@end - +@end namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ + * ObjC++ class for module 'SampleTurboModule' + */ class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { public: NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react } // namespace facebook + + + +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = @(const1); + auto const2 = i.const2.get(); + d[@\\"const2\\"] = @(const2); + auto const3 = i.const3.get(); + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} ", } `; @@ -1412,40 +1080,45 @@ Map { - - @protocol NativeSample2TurboModuleSpec -- (void) voidFunc; -@end - +- (void)voidFunc; +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'Sample2TurboModule' + */ + class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook @protocol NativeSampleTurboModuleSpec -- (void) voidFunc; -@end +- (void)voidFunc; +@end namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ + * ObjC++ class for module 'SampleTurboModule' + */ class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { public: NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; - /** - * ObjC++ class for module 'Sample2TurboModule' - */ - class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; } // namespace react } // namespace facebook + + + + ", } `; @@ -1484,39 +1157,45 @@ Map { - - @protocol NativeSample2TurboModuleSpec -- (void) voidFunc; -@end +- (void)voidFunc; +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'Sample2TurboModule' + */ + class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook @protocol NativeSampleTurboModuleSpec -- (void) voidFunc; -@end +- (void)voidFunc; +@end namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ + * ObjC++ class for module 'SampleTurboModule' + */ class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { public: NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; - /** - * ObjC++ class for module 'Sample2TurboModule' - */ - class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; } // namespace react } // namespace facebook + + + + ", } `; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index 192e19235d1cf1..1d9e6034f4baeb 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -9,17 +9,21 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" + -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultReturnType) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultReturnType:(id)json +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end @@ -32,72 +36,83 @@ Map { @end -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(id)json +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptions) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptions:(id)json +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptions) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptions:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end namespace facebook { namespace react { - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"difficult\\", @selector(difficult:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"difficult\\", @selector(difficult:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"optionals\\", @selector(optionals:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"optionals\\", @selector(optionals:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"optionalMethod\\", @selector(optionalMethod:callback:extras:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"optionalMethod\\", @selector(optionalMethod:callback:extras:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"getArrays\\", @selector(getArrays:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArrays(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getArrays\\", @selector(getArrays:), args, count); } + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; - methodMap_[\\"optionals\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionals}; - methodMap_[\\"optionalMethod\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; - methodMap_[\\"getArrays\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays}; - setMethodArgConversionSelector(@\\"difficult\\", 0, @\\"JS_NativeSampleTurboModule_SpecDifficultA:\\"); - setMethodArgConversionSelector(@\\"optionals\\", 0, @\\"JS_NativeSampleTurboModule_SpecOptionalsA:\\"); - setMethodArgConversionSelector(@\\"getArrays\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetArraysOptions:\\"); + + methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; + setMethodArgConversionSelector(@\\"difficult\\", 0, @\\"JS_NativeSampleTurboModule_SpecDifficultA:\\"); + + + methodMap_[\\"optionals\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionals}; + setMethodArgConversionSelector(@\\"optionals\\", 0, @\\"JS_NativeSampleTurboModule_SpecOptionalsA:\\"); + + + methodMap_[\\"optionalMethod\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; + + + + methodMap_[\\"getArrays\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays}; + setMethodArgConversionSelector(@\\"getArrays\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetArraysOptions:\\"); + + } } } // namespace react } // namespace facebook + ", } `; @@ -111,23 +126,29 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" + namespace facebook { namespace react { - + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - + + } } } // namespace react } // namespace facebook + ", } `; @@ -141,20 +162,16 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" -@implementation RCTCxxConvert (NativeAliasTurboModule_Options) -+ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - @implementation RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) + (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json @@ -179,23 +196,33 @@ Map { } @end -namespace facebook { - namespace react { +@implementation RCTCxxConvert (NativeAliasTurboModule_Options) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json +{ + return facebook::react::managedPointer(json); +} +@end - static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count); +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI::cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count); } + NativeAliasTurboModuleSpecJSI::NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - - methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; - setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_Options:\\"); + + methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; + setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_SpecCropImageCropData:\\"); + + } } } // namespace react } // namespace facebook + ", } `; @@ -209,35 +236,15 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import - +#import \\"SampleSpec.h\\" -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json -{ - return facebook::react::managedPointer(json); -} -@end @implementation RCTCxxConvert (NativeCameraRollManager_GetPhotosParams) @@ -247,37 +254,43 @@ Map { } @end +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count); + } -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json -{ - return facebook::react::managedPointer(json); -} -@end + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count); + } -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json -{ - return facebook::react::managedPointer(json); -} -@end + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count); + } -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json -{ - return facebook::react::managedPointer(json); -} -@end + NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; + setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_SpecGetPhotosParams:\\"); + + + methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; + + + + methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos}; + + + } + } + } // namespace react +} // namespace facebook -@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) -+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json -{ - return facebook::react::managedPointer(json); -} -@end @implementation RCTCxxConvert (NativeExceptionsManager_StackFrame) @@ -297,79 +310,87 @@ Map { namespace facebook { namespace react { + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count); + } - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count); + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count); - } - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count); + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count); } - NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - - methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; - methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; - methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos}; - setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_GetPhotosParams:\\"); + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count); + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count); } - NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) + + NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; - setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); - } + + methodMap_[\\"reportFatalException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; + - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count); - } + + methodMap_[\\"reportSoftException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; + - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count); - } + + methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException}; + setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_SpecReportExceptionData:\\"); - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count); - } + + methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; + + + + methodMap_[\\"dismissRedbox\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; + - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count); + } } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) ++ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json +{ + return facebook::react::managedPointer(json); +} +@end - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count); +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI::openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count); } - NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) + + NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; - methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; - methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException}; - methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; - methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; - setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_ExceptionData:\\"); + + methodMap_[\\"openCameraDialog\\"] = MethodMetadata {1, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; + setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); + + } } } // namespace react } // namespace facebook + ", } `; @@ -383,87 +404,142 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" + +@implementation RCTCxxConvert (NativeSampleTurboModule_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + namespace facebook { namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, BooleanKind, \\"getBool\\", @selector(getBool:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); } + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; - methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; - methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; - methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; - methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; - methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; - methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; - methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; + + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + + + } } } // namespace react } // namespace facebook + ", } `; @@ -477,40 +553,57 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" namespace facebook { namespace react { - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + + NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + + } } + } // namespace react +} // namespace facebook + - static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + } } } // namespace react } // namespace facebook + ", } `; @@ -524,38 +617,57 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" namespace facebook { namespace react { - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + + NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + + } } + } // namespace react +} // namespace facebook + - static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + } } } // namespace react } // namespace facebook + ", } `; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap deleted file mode 100644 index 75bb7bfe5dbde1..00000000000000 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap +++ /dev/null @@ -1,284 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GenerateStructs can generate fixture SIMPLE_CONSTANTS 1`] = ` -" - -namespace JS { - namespace NativeSampleTurboModule { - struct ConstantsDG { - - struct Builder { - struct Input { - RCTRequired h; - RCTRequired i; - RCTRequired j; - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing ConstantsDG */ - Builder(ConstantsDG i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static ConstantsDG fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - ConstantsDG(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -inline JS::NativeSampleTurboModule::ConstantsDG::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto h = i.h.get(); - d[@\\"h\\"] = @(h); -auto i = i.i.get(); - d[@\\"i\\"] = @(i); -auto j = i.j.get(); - d[@\\"j\\"] = j; - return d; -}) {} -inline JS::NativeSampleTurboModule::ConstantsDG::Builder::Builder(ConstantsDG i) : _factory(^{ - return i.unsafeRawValue(); -}) {} - -namespace JS { - namespace NativeSampleTurboModule { - struct ConstantsD { - - struct Builder { - struct Input { - RCTRequired e; - RCTRequired f; - RCTRequired g; - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing ConstantsD */ - Builder(ConstantsD i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static ConstantsD fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - ConstantsD(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -inline JS::NativeSampleTurboModule::ConstantsD::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto e = i.e.get(); - d[@\\"e\\"] = @(e); -auto f = i.f.get(); - d[@\\"f\\"] = @(f); -auto g = i.g.get(); - d[@\\"g\\"] = g.buildUnsafeRawValue(); - return d; -}) {} -inline JS::NativeSampleTurboModule::ConstantsD::Builder::Builder(ConstantsD i) : _factory(^{ - return i.unsafeRawValue(); -}) {} - -namespace JS { - namespace NativeSampleTurboModule { - struct Constants { - - struct Builder { - struct Input { - RCTRequired a; - RCTRequired b; - RCTRequired c; - RCTRequired d; - RCTRequired k; - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing Constants */ - Builder(Constants i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - Constants(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto a = i.a.get(); - d[@\\"a\\"] = @(a); -auto b = i.b.get(); - d[@\\"b\\"] = @(b); -auto c = i.c.get(); - d[@\\"c\\"] = c; -auto d = i.d.get(); - d[@\\"d\\"] = d.buildUnsafeRawValue(); -auto k = i.k.get(); - d[@\\"k\\"] = @(k); - return d; -}) {} -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ - return i.unsafeRawValue(); -}) {} -" -`; - -exports[`GenerateStructs can generate fixture SIMPLE_STRUCT 1`] = ` -" - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnTypeDG { - bool h() const; - double i() const; - NSString *j() const; - - SpecSampleFuncReturnTypeDG(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnTypeDG) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnTypeDG:(id)json; -@end - - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnTypeD { - bool e() const; - double f() const; - JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG g() const; - - SpecSampleFuncReturnTypeD(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnTypeD) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnTypeD:(id)json; -@end - - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnType { - bool a() const; - double b() const; - NSString *c() const; - JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD d() const; - double k() const; - - SpecSampleFuncReturnType(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnType) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnType:(id)json; -@end - -inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnType::a() const -{ - id const p = _v[@\\"a\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnType::b() const -{ - id const p = _v[@\\"b\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeSampleTurboModule::SpecSampleFuncReturnType::c() const -{ - id const p = _v[@\\"c\\"]; - return RCTBridgingToString(p); -} - - -inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD JS::NativeSampleTurboModule::SpecSampleFuncReturnType::d() const -{ - id const p = _v[@\\"d\\"]; - return JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnType::k() const -{ - id const p = _v[@\\"k\\"]; - return RCTBridgingToDouble(p); -} - - -inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::e() const -{ - id const p = _v[@\\"e\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::f() const -{ - id const p = _v[@\\"f\\"]; - return RCTBridgingToDouble(p); -} - - -inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::g() const -{ - id const p = _v[@\\"g\\"]; - return JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG(p); -} - - -inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::h() const -{ - id const p = _v[@\\"h\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::i() const -{ - id const p = _v[@\\"i\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::j() const -{ - id const p = _v[@\\"j\\"]; - return RCTBridgingToString(p); -} - -" -`; From 1ac1255d63320d547bc967ff72dfdd3e55562e73 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 26/52] E2E snapshot test ObjC++ generator Summary: NativeModule specs exist under `react-native-github/packages/react-native-codegen/src/__tests__/modules/fixtures`. `GenerateModuleObjCpp-test.js` runs the RN Codegen on those NativeModule specs, and saves the output inside a snapshot. For convenience, the folowing command runs the legacy codegen on the fixtures: ``` buck build fbsource//xplat/js/react-native-github/packages/react-native-codegen/src/__tests__/modules:RNCodegenModuleFixtures-flow-types-ios --show-output ``` Changelog: [Internal] Reviewed By: hramos Differential Revision: D23637708 fbshipit-source-id: 3319f319515eca42b4499682313fea6e0bdc2a06 --- .../modules/NativeSampleTurboModule.js | 18 +- .../modules/NativeSampleTurboModuleArrays.js | 51 + .../NativeSampleTurboModuleNullable.js | 46 + ...iveSampleTurboModuleNullableAndOptional.js | 46 + .../NativeSampleTurboModuleOptional.js | 46 + .../e2e/__tests__/modules/BUCK | 11 + .../modules/GenerateModuleObjCpp-test.js | 50 + .../GenerateModuleObjCpp-test.js.snap | 2545 +++++++++++++++++ 8 files changed, 2811 insertions(+), 2 deletions(-) create mode 100644 packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleArrays.js create mode 100644 packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullable.js create mode 100644 packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullableAndOptional.js create mode 100644 packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleOptional.js create mode 100644 packages/react-native-codegen/e2e/__tests__/modules/BUCK create mode 100644 packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js create mode 100644 packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModule.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModule.js index ee6c0983afb75f..c950ed9e288972 100644 --- a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModule.js +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModule.js @@ -10,9 +10,16 @@ 'use strict'; -import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; +import type { + RootTag, + TurboModule, +} from 'react-native/Libraries/TurboModule/RCTExport'; import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; +type Animal = {| + name: string, +|}; + export interface Spec extends TurboModule { // Exported methods. +getConstants: () => {| @@ -26,7 +33,14 @@ export interface Spec extends TurboModule { +getString: (arg: string) => string; +getArray: (arg: Array) => Array; +getObject: (arg: Object) => Object; - +getValue: (x: number, y: string, z: Object) => Object; + +getObjectShape: (arg: {|prop: number|}) => {|prop: number|}; + +getAlias: (arg: Animal) => Animal; + +getRootTag: (arg: RootTag) => RootTag; + +getValue: ( + x: number, + getValuegetValuegetValuegetValuegetValuey: string, + z: Object, + ) => Object; +getValueWithCallback: (callback: (value: string) => void) => void; +getValueWithPromise: (error: boolean) => Promise; } diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleArrays.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleArrays.js new file mode 100644 index 00000000000000..fce6f7c0f0fb6a --- /dev/null +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleArrays.js @@ -0,0 +1,51 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type { + RootTag, + TurboModule, +} from 'react-native/Libraries/TurboModule/RCTExport'; +import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; + +type Animal = {| + name: string, +|}; + +export interface Spec extends TurboModule { + // Exported methods. + +getConstants: () => {| + const1: Array, + const2: Array, + const3: Array, + id?: Array, + |}; + +voidFunc: () => void; + +getBool: (id: Array) => Array; + +getNumber: (arg: Array) => Array; + +getString: (arg: Array) => Array; + +getArray: (arg: Array>) => Array>; + +getObject: (arg: Array) => Array; + +getObjectShape: (arg: Array<{|prop: number|}>) => Array<{|prop: number|}>; + +getAlias: (arg: Array) => Array; + +getRootTag: (arg: Array) => Array; + +getValue: ( + x: Array, + y: Array, + z: Array, + ) => Array; + +getValueWithCallback: (callback: (value: Array) => void) => void; + +getValueWithPromise: (error: Array) => Promise>; +} + +export default (TurboModuleRegistry.getEnforcing( + 'SampleTurboModuleArrays', +): Spec); diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullable.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullable.js new file mode 100644 index 00000000000000..ac7b57e386a2d0 --- /dev/null +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullable.js @@ -0,0 +1,46 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type { + RootTag, + TurboModule, +} from 'react-native/Libraries/TurboModule/RCTExport'; +import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; + +type Animal = ?{| + name: ?string, +|}; + +export interface Spec extends TurboModule { + // Exported methods. + +getConstants: () => {| + const1: ?boolean, + const2: ?number, + const3: ?string, + |}; + +voidFunc: () => void; + +getBool: (arg: ?boolean) => ?boolean; + +getNumber: (arg: ?number) => ?number; + +getString: (arg: ?string) => ?string; + +getArray: (arg: ?Array) => ?Array; + +getObject: (arg: ?Object) => ?Object; + +getObjectShape: (arg: ?{|prop: ?number|}) => ?{|prop: ?number|}; + +getAlias: (arg: ?Animal) => ?Animal; + +getRootTag: (arg: ?RootTag) => ?RootTag; + +getValue: (x: ?number, y: ?string, z: ?Object) => ?Object; + +getValueWithCallback: (callback: (value: ?string) => void) => void; + +getValueWithPromise: (error: ?boolean) => ?Promise; +} + +export default (TurboModuleRegistry.getEnforcing( + 'SampleTurboModuleNullable', +): Spec); diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullableAndOptional.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullableAndOptional.js new file mode 100644 index 00000000000000..29e54d8a5c3693 --- /dev/null +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleNullableAndOptional.js @@ -0,0 +1,46 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type { + RootTag, + TurboModule, +} from 'react-native/Libraries/TurboModule/RCTExport'; +import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; + +type Animal = ?{| + name?: ?string, +|}; + +export interface Spec extends TurboModule { + // Exported methods. + +getConstants?: () => {| + const1?: ?boolean, + const2?: ?number, + const3?: ?string, + |}; + +voidFunc?: () => void; + +getBool?: (arg?: ?boolean) => ?boolean; + +getNumber?: (arg?: ?number) => ?number; + +getString?: (arg?: ?string) => ?string; + +getArray?: (arg?: ?Array) => ?Array; + +getObject?: (arg?: ?Object) => ?Object; + +getObjectShape?: (arg?: {|prop?: ?number|}) => {|prop?: ?number|}; + +getAlias?: (arg?: ?Animal) => ?Animal; + +getRootTag?: (arg?: ?RootTag) => ?RootTag; + +getValue?: (x?: ?number, y?: ?string, z?: ?Object) => ?Object; + +getValueWithCallback?: (callback?: ?(value?: ?string) => void) => void; + +getValueWithPromise?: (error?: ?boolean) => ?Promise; +} + +export default (TurboModuleRegistry.getEnforcing( + 'SampleTurboModuleNullableAndOptional', +): Spec); diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleOptional.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleOptional.js new file mode 100644 index 00000000000000..9f12225a2d883b --- /dev/null +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeSampleTurboModuleOptional.js @@ -0,0 +1,46 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type { + RootTag, + TurboModule, +} from 'react-native/Libraries/TurboModule/RCTExport'; +import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; + +type Animal = {| + name?: string, +|}; + +export interface Spec extends TurboModule { + // Exported methods. + +getConstants?: () => {| + const1?: boolean, + const2?: number, + const3?: string, + |}; + +voidFunc?: () => void; + +getBool?: (arg?: boolean) => boolean; + +getNumber?: (arg?: number) => number; + +getString?: (arg?: string) => string; + +getArray?: (arg?: Array) => Array; + +getObject?: (arg?: Object) => Object; + +getObjectShape?: (arg?: {|prop?: number|}) => {|prop?: number|}; + +getAlias?: (arg?: Animal) => Animal; + +getRootTag?: (arg?: RootTag) => RootTag; + +getValue?: (x?: number, y?: string, z?: Object) => Object; + +getValueWithCallback?: (callback?: (value?: string) => void) => void; + +getValueWithPromise?: (error?: boolean) => Promise; +} + +export default (TurboModuleRegistry.getEnforcing( + 'SampleTurboModuleOptional', +): Spec); diff --git a/packages/react-native-codegen/e2e/__tests__/modules/BUCK b/packages/react-native-codegen/e2e/__tests__/modules/BUCK new file mode 100644 index 00000000000000..29df252313e6ea --- /dev/null +++ b/packages/react-native-codegen/e2e/__tests__/modules/BUCK @@ -0,0 +1,11 @@ +load("@fbsource//xplat/js/RKJSModules/Libraries/NativeModules:defs.bzl", "react_native_module_flow_types_library") + +react_native_module_flow_types_library( + name = "RNCodegenModuleFixtures", + android_package_name = "com.facebook.fbreact.specs", + js_srcs = glob( + [ + "../../__test_fixtures__/modules/*.js", + ], + ), +) diff --git a/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js b/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js new file mode 100644 index 00000000000000..2b2deec0b0fe33 --- /dev/null +++ b/packages/react-native-codegen/e2e/__tests__/modules/GenerateModuleObjCpp-test.js @@ -0,0 +1,50 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails oncall+react_native + * @flow strict-local + * @format + */ + +'use strict'; + +const parser = require('../../../src/parsers/flow'); +const generator = require('../../../src/generators/modules/GenerateModuleObjCpp'); +const fs = require('fs'); + +import type {SchemaType} from '../../../src/CodegenSchema'; + +const FIXTURE_DIR = `${__dirname}/../../__test_fixtures__/modules`; + +function getModules(): SchemaType { + const filenames: Array = fs.readdirSync(FIXTURE_DIR); + return filenames.reduce( + (accumulator, file) => { + const schema = parser.parseFile(`${FIXTURE_DIR}/${file}`); + return { + modules: { + ...accumulator.modules, + ...schema.modules, + }, + }; + }, + {modules: {}}, + ); +} + +describe('GenerateModuleObjCpp', () => { + it('can generate a header file NativeModule specs', () => { + const libName = 'RNCodegenModuleFixtures'; + const output = generator.generate(libName, getModules(), libName); + expect(output.get(libName + '.h')).toMatchSnapshot(); + }); + + it('can generate an implementation file NativeModule specs', () => { + const libName = 'RNCodegenModuleFixtures'; + const output = generator.generate(libName, getModules(), libName); + expect(output.get(libName + '-generated.mm')).toMatchSnapshot(); + }); +}); diff --git a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap new file mode 100644 index 00000000000000..73bfce8a865d1b --- /dev/null +++ b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap @@ -0,0 +1,2545 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GenerateModuleObjCpp can generate a header file NativeModule specs 1`] = ` +" +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif + +#import + +#import + +#import + +#import +#import +#import + +#import +#import +#import + +#import + + + +@protocol NativeArrayTurboModuleSpec + +- (NSArray *)getArray:(NSArray *)a; +- (NSArray *)getReadOnlyArray:(NSArray *)a; +- (NSArray *)getArrayWithAlias:(NSArray *)a + b:(NSArray *)b; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ArrayTurboModule' + */ + class JSI_EXPORT NativeArrayTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeArrayTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +@protocol NativeBooleanTurboModuleSpec + +- (NSNumber *)getBoolean:(BOOL)arg; +- (NSNumber *)getBooleanWithAlias:(BOOL)arg; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'BooleanTurboModule' + */ + class JSI_EXPORT NativeBooleanTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeBooleanTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +@protocol NativeCallbackTurboModuleSpec + +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithCallbackWithAlias:(RCTResponseSenderBlock)c; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'CallbackTurboModule' + */ + class JSI_EXPORT NativeCallbackTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeCallbackTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +@protocol NativeNullableTurboModuleSpec + +- (NSNumber * _Nullable)getBool:(NSNumber *)a; +- (NSNumber * _Nullable)getNumber:(NSNumber *)a; +- (NSString * _Nullable)getString:(NSNumber *)a; +- (NSArray> * _Nullable)getArray:(NSArray * _Nullable)a; +- (NSDictionary * _Nullable)getObject:(NSDictionary * _Nullable)a; +- (void)getValueWithPromise:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NullableTurboModule' + */ + class JSI_EXPORT NativeNullableTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeNullableTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +@protocol NativeNumberTurboModuleSpec + +- (NSNumber *)getNumber:(double)arg; +- (NSNumber *)getNumberWithAlias:(double)arg; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'NumberTurboModule' + */ + class JSI_EXPORT NativeNumberTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeNumberTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeObjectTurboModule { + struct SpecDifficultObjectAE { + bool D() const; + double E() const; + NSString *F() const; + + SpecDifficultObjectAE(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeObjectTurboModule_SpecDifficultObjectAE) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_SpecDifficultObjectAE:(id)json; +@end + + +namespace JS { + namespace NativeObjectTurboModule { + struct SpecDifficultObjectA { + bool D() const; + JS::NativeObjectTurboModule::SpecDifficultObjectAE E() const; + NSString *F() const; + + SpecDifficultObjectA(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeObjectTurboModule_SpecDifficultObjectA) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_SpecDifficultObjectA:(id)json; +@end + + +namespace JS { + namespace NativeObjectTurboModule { + struct ConstantsEEE { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEEE */ + Builder(ConstantsEEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeObjectTurboModule { + struct ConstantsEE { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEE */ + Builder(ConstantsEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeObjectTurboModule { + struct ConstantsE { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsE */ + Builder(ConstantsE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeObjectTurboModule { + struct Constants { + + struct Builder { + struct Input { + RCTRequired D; + RCTRequired E; + RCTRequired F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeObjectTurboModuleSpec + +- (NSDictionary *)getGenericObject:(NSDictionary *)arg; +- (NSDictionary *)getGenericObjectReadOnly:(NSDictionary *)arg; +- (NSDictionary *)getGenericObjectWithAlias:(NSDictionary *)arg; +- (NSDictionary *)difficultObject:(JS::NativeObjectTurboModule::SpecDifficultObjectA &)A; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ObjectTurboModule' + */ + class JSI_EXPORT NativeObjectTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct ConstantsEEE { + + struct Builder { + struct Input { + folly::Optional D; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEEE */ + Builder(ConstantsEEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct ConstantsEE { + + struct Builder { + struct Input { + folly::Optional D; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsEE */ + Builder(ConstantsEE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsEE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsEE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct ConstantsE { + + struct Builder { + struct Input { + folly::Optional D; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsE */ + Builder(ConstantsE i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsE fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsE(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeOptionalObjectTurboModule { + struct Constants { + + struct Builder { + struct Input { + folly::Optional D; + id _Nullable A; + folly::Optional E; + NSString *F; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeOptionalObjectTurboModuleSpec + +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'OptionalObjectTurboModule' + */ + class JSI_EXPORT NativeOptionalObjectTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeOptionalObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +@protocol NativePromiseTurboModuleSpec + +- (void)getValueWithPromise:(BOOL)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)getValueWithPromiseWithAlias:(NSString *)arg + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'PromiseTurboModule' + */ + class JSI_EXPORT NativePromiseTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativePromiseTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeSampleTurboModule { + struct SpecGetObjectShapeArg { + double prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetObjectShapeArg:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModule { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_Animal:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModule { + struct Constants { + + struct Builder { + struct Input { + RCTRequired const1; + RCTRequired const2; + RCTRequired const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleSpec + +- (void)voidFunc; +- (NSNumber *)getBool:(BOOL)arg; +- (NSNumber *)getNumber:(double)arg; +- (NSString *)getString:(NSString *)arg; +- (NSArray> *)getArray:(NSArray *)arg; +- (NSDictionary *)getObject:(NSDictionary *)arg; +- (NSDictionary *)getObjectShape:(JS::NativeSampleTurboModule::SpecGetObjectShapeArg &)arg; +- (NSDictionary *)getAlias:(JS::NativeSampleTurboModule::Animal &)arg; +- (NSNumber *)getRootTag:(double)arg; +- (NSDictionary *)getValue:(double)x +getValuegetValuegetValuegetValuegetValuey:(NSString *)getValuegetValuegetValuegetValuegetValuey + z:(NSDictionary *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(BOOL)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeSampleTurboModuleArrays { + struct ConstantsIdElement { + + struct Builder { + struct Input { + RCTRequired prop; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsIdElement */ + Builder(ConstantsIdElement i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ConstantsIdElement fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsIdElement(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +namespace JS { + namespace NativeSampleTurboModuleArrays { + struct Constants { + + struct Builder { + struct Input { + RCTRequired> const1; + RCTRequired> const2; + RCTRequired> const3; + folly::Optional>> id_; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleArraysSpec + +- (void)voidFunc; +- (NSArray *)getBool:(NSArray *)id; +- (NSArray *)getNumber:(NSArray *)arg; +- (NSArray *)getString:(NSArray *)arg; +- (NSArray> *> *)getArray:(NSArray *)arg; +- (NSArray *)getObject:(NSArray *)arg; +- (NSArray *)getObjectShape:(NSArray *)arg; +- (NSArray *)getAlias:(NSArray *)arg; +- (NSArray *)getRootTag:(NSArray *)arg; +- (NSArray *)getValue:(NSArray *)x + y:(NSArray *)y + z:(NSArray *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSArray *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModuleArrays' + */ + class JSI_EXPORT NativeSampleTurboModuleArraysSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleArraysSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeSampleTurboModuleNullable { + struct SpecGetObjectShapeArg { + folly::Optional prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullable_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_SpecGetObjectShapeArg:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModuleNullable { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullable_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_Animal:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModuleNullable { + struct Constants { + + struct Builder { + struct Input { + RCTRequired> const1; + RCTRequired> const2; + RCTRequired const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleNullableSpec + +- (void)voidFunc; +- (NSNumber * _Nullable)getBool:(NSNumber *)arg; +- (NSNumber * _Nullable)getNumber:(NSNumber *)arg; +- (NSString * _Nullable)getString:(NSString * _Nullable)arg; +- (NSArray> * _Nullable)getArray:(NSArray * _Nullable)arg; +- (NSDictionary * _Nullable)getObject:(NSDictionary * _Nullable)arg; +- (NSDictionary * _Nullable)getObjectShape:(JS::NativeSampleTurboModuleNullable::SpecGetObjectShapeArg &)arg; +- (NSDictionary * _Nullable)getAlias:(JS::NativeSampleTurboModuleNullable::Animal &)arg; +- (NSNumber * _Nullable)getRootTag:(NSNumber *)arg; +- (NSDictionary * _Nullable)getValue:(NSNumber *)x + y:(NSString * _Nullable)y + z:(NSDictionary * _Nullable)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSNumber *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModuleNullable' + */ + class JSI_EXPORT NativeSampleTurboModuleNullableSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleNullableSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeSampleTurboModuleNullableAndOptional { + struct SpecGetObjectShapeArg { + folly::Optional prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModuleNullableAndOptional { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_Animal:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModuleNullableAndOptional { + struct Constants { + + struct Builder { + struct Input { + folly::Optional const1; + folly::Optional const2; + NSString *const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleNullableAndOptionalSpec + +- (void)voidFunc; +- (NSNumber * _Nullable)getBool:(NSNumber *)arg; +- (NSNumber * _Nullable)getNumber:(NSNumber *)arg; +- (NSString * _Nullable)getString:(NSString * _Nullable)arg; +- (NSArray> * _Nullable)getArray:(NSArray * _Nullable)arg; +- (NSDictionary * _Nullable)getObject:(NSDictionary * _Nullable)arg; +- (NSDictionary *)getObjectShape:(JS::NativeSampleTurboModuleNullableAndOptional::SpecGetObjectShapeArg &)arg; +- (NSDictionary * _Nullable)getAlias:(JS::NativeSampleTurboModuleNullableAndOptional::Animal &)arg; +- (NSNumber * _Nullable)getRootTag:(NSNumber *)arg; +- (NSDictionary * _Nullable)getValue:(NSNumber *)x + y:(NSString * _Nullable)y + z:(NSDictionary * _Nullable)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSNumber *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModuleNullableAndOptional' + */ + class JSI_EXPORT NativeSampleTurboModuleNullableAndOptionalSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleNullableAndOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeSampleTurboModuleOptional { + struct SpecGetObjectShapeArg { + folly::Optional prop() const; + + SpecGetObjectShapeArg(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleOptional_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_SpecGetObjectShapeArg:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModuleOptional { + struct Animal { + NSString *name() const; + + Animal(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModuleOptional_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_Animal:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModuleOptional { + struct Constants { + + struct Builder { + struct Input { + folly::Optional const1; + folly::Optional const2; + NSString *const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} +@protocol NativeSampleTurboModuleOptionalSpec + +- (void)voidFunc; +- (NSNumber *)getBool:(NSNumber *)arg; +- (NSNumber *)getNumber:(NSNumber *)arg; +- (NSString *)getString:(NSString *)arg; +- (NSArray> *)getArray:(NSArray *)arg; +- (NSDictionary *)getObject:(NSDictionary *)arg; +- (NSDictionary *)getObjectShape:(JS::NativeSampleTurboModuleOptional::SpecGetObjectShapeArg &)arg; +- (NSDictionary *)getAlias:(JS::NativeSampleTurboModuleOptional::Animal &)arg; +- (NSNumber *)getRootTag:(NSNumber *)arg; +- (NSDictionary *)getValue:(NSNumber *)x + y:(NSString *)y + z:(NSDictionary *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(NSNumber *)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModuleOptional' + */ + class JSI_EXPORT NativeSampleTurboModuleOptionalSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +@protocol NativeStringTurboModuleSpec + +- (NSString *)getString:(NSString *)arg; +- (NSString *)getStringWithAlias:(NSString *)arg; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'StringTurboModule' + */ + class JSI_EXPORT NativeStringTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeStringTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + + + + + + +inline bool JS::NativeObjectTurboModule::SpecDifficultObjectAE::D() const +{ + id const p = _v[@\\"D\\"]; + return RCTBridgingToBool(p); +} + + +inline double JS::NativeObjectTurboModule::SpecDifficultObjectAE::E() const +{ + id const p = _v[@\\"E\\"]; + return RCTBridgingToDouble(p); +} + + +inline NSString *JS::NativeObjectTurboModule::SpecDifficultObjectAE::F() const +{ + id const p = _v[@\\"F\\"]; + return RCTBridgingToString(p); +} + + +inline bool JS::NativeObjectTurboModule::SpecDifficultObjectA::D() const +{ + id const p = _v[@\\"D\\"]; + return RCTBridgingToBool(p); +} + + +inline JS::NativeObjectTurboModule::SpecDifficultObjectAE JS::NativeObjectTurboModule::SpecDifficultObjectA::E() const +{ + id const p = _v[@\\"E\\"]; + return JS::NativeObjectTurboModule::SpecDifficultObjectAE(p); +} + + +inline NSString *JS::NativeObjectTurboModule::SpecDifficultObjectA::F() const +{ + id const p = _v[@\\"F\\"]; + return RCTBridgingToString(p); +} + + +inline JS::NativeObjectTurboModule::ConstantsEEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = @(E); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::ConstantsEEE::Builder::Builder(ConstantsEEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeObjectTurboModule::ConstantsEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = E.buildUnsafeRawValue(); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::ConstantsEE::Builder::Builder(ConstantsEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeObjectTurboModule::ConstantsE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = E.buildUnsafeRawValue(); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::ConstantsE::Builder::Builder(ConstantsE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeObjectTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D.get(); + d[@\\"D\\"] = @(D); + auto E = i.E.get(); + d[@\\"E\\"] = E.buildUnsafeRawValue(); + auto F = i.F.get(); + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeObjectTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeOptionalObjectTurboModule::ConstantsEEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? @((double)E.value()) : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsEEE::Builder::Builder(ConstantsEEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeOptionalObjectTurboModule::ConstantsEE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? E.value().buildUnsafeRawValue() : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsEE::Builder::Builder(ConstantsEE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeOptionalObjectTurboModule::ConstantsE::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? E.value().buildUnsafeRawValue() : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::ConstantsE::Builder::Builder(ConstantsE i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto D = i.D; + d[@\\"D\\"] = D.hasValue() ? @((BOOL)D.value()) : nil; + auto A = i.A; + d[@\\"A\\"] = A; + auto E = i.E; + d[@\\"E\\"] = E.hasValue() ? E.value().buildUnsafeRawValue() : nil; + auto F = i.F; + d[@\\"F\\"] = F; + return d; +}) {} +inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + + +inline double JS::NativeSampleTurboModule::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToDouble(p); +} + + +inline NSString *JS::NativeSampleTurboModule::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToString(p); +} + + +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = @(const1); + auto const2 = i.const2.get(); + d[@\\"const2\\"] = @(const2); + auto const3 = i.const3.get(); + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeSampleTurboModuleArrays::ConstantsIdElement::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto prop = i.prop.get(); + d[@\\"prop\\"] = @(prop); + return d; +}) {} +inline JS::NativeSampleTurboModuleArrays::ConstantsIdElement::Builder::Builder(ConstantsIdElement i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline JS::NativeSampleTurboModuleArrays::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = RCTConvertVecToArray(const1, ^id(bool el_) { return @(el_); }); + auto const2 = i.const2.get(); + d[@\\"const2\\"] = RCTConvertVecToArray(const2, ^id(double el_) { return @(el_); }); + auto const3 = i.const3.get(); + d[@\\"const3\\"] = RCTConvertVecToArray(const3, ^id(NSString * el_) { return el_; }); + auto id_ = i.id_; + d[@\\"id_\\"] = RCTConvertOptionalVecToArray(id_, ^id(folly::Optional el_) { return el_.hasValue() ? el_.value().buildUnsafeRawValue() : nil; }); + return d; +}) {} +inline JS::NativeSampleTurboModuleArrays::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline folly::Optional JS::NativeSampleTurboModuleNullable::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline NSString *JS::NativeSampleTurboModuleNullable::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline JS::NativeSampleTurboModuleNullable::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = const1.hasValue() ? @((BOOL)const1.value()) : nil; + auto const2 = i.const2.get(); + d[@\\"const2\\"] = const2.hasValue() ? @((double)const2.value()) : nil; + auto const3 = i.const3.get(); + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModuleNullable::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline folly::Optional JS::NativeSampleTurboModuleNullableAndOptional::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline NSString *JS::NativeSampleTurboModuleNullableAndOptional::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline JS::NativeSampleTurboModuleNullableAndOptional::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1; + d[@\\"const1\\"] = const1.hasValue() ? @((BOOL)const1.value()) : nil; + auto const2 = i.const2; + d[@\\"const2\\"] = const2.hasValue() ? @((double)const2.value()) : nil; + auto const3 = i.const3; + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModuleNullableAndOptional::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +inline folly::Optional JS::NativeSampleTurboModuleOptional::SpecGetObjectShapeArg::prop() const +{ + id const p = _v[@\\"prop\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline NSString *JS::NativeSampleTurboModuleOptional::Animal::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline JS::NativeSampleTurboModuleOptional::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1; + d[@\\"const1\\"] = const1.hasValue() ? @((BOOL)const1.value()) : nil; + auto const2 = i.const2; + d[@\\"const2\\"] = const2.hasValue() ? @((double)const2.value()) : nil; + auto const3 = i.const3; + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModuleOptional::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +" +`; + +exports[`GenerateModuleObjCpp can generate an implementation file NativeModule specs 1`] = ` +" +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. + */ + +#import \\"RNCodegenModuleFixtures.h\\" + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI::getReadOnlyArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getReadOnlyArray\\", @selector(getReadOnlyArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI::getArrayWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArrayWithAlias\\", @selector(getArrayWithAlias:b:), args, count); + } + + + NativeArrayTurboModuleSpecJSI::NativeArrayTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeArrayTurboModuleSpecJSI_getArray}; + + + + methodMap_[\\"getReadOnlyArray\\"] = MethodMetadata {1, __hostFunction_NativeArrayTurboModuleSpecJSI_getReadOnlyArray}; + + + + methodMap_[\\"getArrayWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeArrayTurboModuleSpecJSI_getArrayWithAlias}; + + + } + } + } // namespace react +} // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeBooleanTurboModuleSpecJSI::getBoolean(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBoolean\\", @selector(getBoolean:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeBooleanTurboModuleSpecJSI::getBooleanWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBooleanWithAlias\\", @selector(getBooleanWithAlias:), args, count); + } + + + NativeBooleanTurboModuleSpecJSI::NativeBooleanTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getBoolean\\"] = MethodMetadata {1, __hostFunction_NativeBooleanTurboModuleSpecJSI_getBoolean}; + + + + methodMap_[\\"getBooleanWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeBooleanTurboModuleSpecJSI_getBooleanWithAlias}; + + + } + } + } // namespace react +} // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeCallbackTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeCallbackTurboModuleSpecJSI::getValueWithCallbackWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallbackWithAlias\\", @selector(getValueWithCallbackWithAlias:), args, count); + } + + + NativeCallbackTurboModuleSpecJSI::NativeCallbackTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeCallbackTurboModuleSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithCallbackWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeCallbackTurboModuleSpecJSI_getValueWithCallbackWithAlias}; + + + } + } + } // namespace react +} // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:reject:), args, count); + } + + + NativeNullableTurboModuleSpecJSI::NativeNullableTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getObject}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getValueWithPromise}; + + + } + } + } // namespace react +} // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeNumberTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeNumberTurboModuleSpecJSI::getNumberWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumberWithAlias\\", @selector(getNumberWithAlias:), args, count); + } + + + NativeNumberTurboModuleSpecJSI::NativeNumberTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeNumberTurboModuleSpecJSI_getNumber}; + + + + methodMap_[\\"getNumberWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeNumberTurboModuleSpecJSI_getNumberWithAlias}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeObjectTurboModule_SpecDifficultObjectAE) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_SpecDifficultObjectAE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeObjectTurboModule_SpecDifficultObjectA) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_SpecDifficultObjectA:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeObjectTurboModule_ConstantsEEE) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_ConstantsEEE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeObjectTurboModule_ConstantsEE) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_ConstantsEE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeObjectTurboModule_ConstantsE) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_ConstantsE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeObjectTurboModule_Constants) ++ (RCTManagedPointer *)JS_NativeObjectTurboModule_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getGenericObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getGenericObject\\", @selector(getGenericObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getGenericObjectReadOnly(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getGenericObjectReadOnly\\", @selector(getGenericObjectReadOnly:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getGenericObjectWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getGenericObjectWithAlias\\", @selector(getGenericObjectWithAlias:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::difficultObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"difficultObject\\", @selector(difficultObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeObjectTurboModuleSpecJSI::NativeObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getGenericObject\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getGenericObject}; + + + + methodMap_[\\"getGenericObjectReadOnly\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getGenericObjectReadOnly}; + + + + methodMap_[\\"getGenericObjectWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getGenericObjectWithAlias}; + + + + methodMap_[\\"difficultObject\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_difficultObject}; + setMethodArgConversionSelector(@\\"difficultObject\\", 0, @\\"JS_NativeObjectTurboModule_SpecDifficultObjectA:\\"); + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_ConstantsEEE) ++ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_ConstantsEEE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_ConstantsEE) ++ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_ConstantsEE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_ConstantsE) ++ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_ConstantsE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_Constants) ++ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeOptionalObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeOptionalObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeOptionalObjectTurboModuleSpecJSI::NativeOptionalObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativePromiseTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativePromiseTurboModuleSpecJSI::getValueWithPromiseWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromiseWithAlias\\", @selector(getValueWithPromiseWithAlias:resolve:reject:), args, count); + } + + + NativePromiseTurboModuleSpecJSI::NativePromiseTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativePromiseTurboModuleSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getValueWithPromiseWithAlias\\"] = MethodMetadata {1, __hostFunction_NativePromiseTurboModuleSpecJSI_getValueWithPromiseWithAlias}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetObjectShapeArg:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModule_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_Animal:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModule_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:getValuegetValuegetValuegetValuegetValuey:z:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; + + + + methodMap_[\\"getObjectShape\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObjectShape}; + setMethodArgConversionSelector(@\\"getObjectShape\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetObjectShapeArg:\\"); + + + methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getAlias}; + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetAliasArg:\\"); + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeSampleTurboModuleArrays_ConstantsIdElement) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleArrays_ConstantsIdElement:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleArrays_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleArrays_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getBool\\", @selector(getBool:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getObject\\", @selector(getObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getAlias\\", @selector(getAlias:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeSampleTurboModuleArraysSpecJSI::NativeSampleTurboModuleArraysSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getObject}; + + + + methodMap_[\\"getObjectShape\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getObjectShape}; + + + + methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getAlias}; + + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeSampleTurboModuleNullable_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_SpecGetObjectShapeArg:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleNullable_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_Animal:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleNullable_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeSampleTurboModuleNullableSpecJSI::NativeSampleTurboModuleNullableSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getObject}; + + + + methodMap_[\\"getObjectShape\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getObjectShape}; + setMethodArgConversionSelector(@\\"getObjectShape\\", 0, @\\"JS_NativeSampleTurboModuleNullable_SpecGetObjectShapeArg:\\"); + + + methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getAlias}; + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleNullable_SpecGetAliasArg:\\"); + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_Animal:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeSampleTurboModuleNullableAndOptionalSpecJSI::NativeSampleTurboModuleNullableAndOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getObject}; + + + + methodMap_[\\"getObjectShape\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getObjectShape}; + setMethodArgConversionSelector(@\\"getObjectShape\\", 0, @\\"JS_NativeSampleTurboModuleNullableAndOptional_SpecGetObjectShapeArg:\\"); + + + methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getAlias}; + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleNullableAndOptional_SpecGetAliasArg:\\"); + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +@implementation RCTCxxConvert (NativeSampleTurboModuleOptional_SpecGetObjectShapeArg) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_SpecGetObjectShapeArg:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleOptional_Animal) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_Animal:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + +@implementation RCTCxxConvert (NativeSampleTurboModuleOptional_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + + NativeSampleTurboModuleOptionalSpecJSI::NativeSampleTurboModuleOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getObject}; + + + + methodMap_[\\"getObjectShape\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getObjectShape}; + setMethodArgConversionSelector(@\\"getObjectShape\\", 0, @\\"JS_NativeSampleTurboModuleOptional_SpecGetObjectShapeArg:\\"); + + + methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getAlias}; + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleOptional_SpecGetAliasArg:\\"); + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants}; + + + } + } + } // namespace react +} // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeStringTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + } + + + static facebook::jsi::Value __hostFunction_NativeStringTurboModuleSpecJSI::getStringWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getStringWithAlias\\", @selector(getStringWithAlias:), args, count); + } + + + NativeStringTurboModuleSpecJSI::NativeStringTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeStringTurboModuleSpecJSI_getString}; + + + + methodMap_[\\"getStringWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeStringTurboModuleSpecJSI_getStringWithAlias}; + + + } + } + } // namespace react +} // namespace facebook + +" +`; From c0408b56fc045cd142c49e635d79e7d39e6ba653 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 27/52] Fix GenerateModuleCpp Summary: Just updating this generator to understand the new RN Codegen Module parser flow types. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23667254 fbshipit-source-id: 558dd7ac5b4541edf40248b8ab8bb50d31fa8624 --- .../generators/modules/GenerateModuleCpp.js | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js index cf02b4095b1c92..deb38646197c44 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js @@ -10,8 +10,15 @@ 'use strict'; -import type {SchemaType} from '../../CodegenSchema'; -const {getTypeAliasTypeAnnotation} = require('./Utils'); +import type { + SchemaType, + NativeModulePropertySchema, + NativeModuleMethodParamSchema, +} from '../../CodegenSchema'; + +import type {AliasResolver} from './Utils'; +const {createAliasResolver, getModules} = require('./Utils'); + type FilesOutput = Map; const propertyHeaderTemplate = @@ -44,7 +51,7 @@ Native::_MODULE_NAME_::CxxSpecJSI::Native::_MODULE_NAME_::CxxSpecJSI(std::shared const template = ` /** - * Copyright (c) Facebook, Inc. and its affiliates. + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -64,16 +71,21 @@ namespace react { } // namespace facebook `; -function traverseArg(arg, index, aliases): string { +function traverseArg( + arg: NativeModuleMethodParamSchema, + index: number, + resolveAlias: AliasResolver, +): string { function wrap(suffix) { return `args[${index}]${suffix}`; } const {typeAnnotation} = arg; - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; + let realTypeAnnotation = typeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': switch (realTypeAnnotation.name) { @@ -90,7 +102,11 @@ function traverseArg(arg, index, aliases): string { case 'BooleanTypeAnnotation': return wrap('.getBool()'); case 'NumberTypeAnnotation': + return wrap('.getNumber()'); case 'FloatTypeAnnotation': + return wrap('.getNumber()'); + case 'DoubleTypeAnnotation': + return wrap('.getNumber()'); case 'Int32TypeAnnotation': return wrap('.getNumber()'); case 'ArrayTypeAnnotation': @@ -98,26 +114,27 @@ function traverseArg(arg, index, aliases): string { case 'FunctionTypeAnnotation': return `std::move(${wrap('.getObject(rt).getFunction(rt)')})`; case 'GenericObjectTypeAnnotation': + return wrap('.getObject(rt)'); case 'ObjectTypeAnnotation': return wrap('.getObject(rt)'); - case 'AnyTypeAnnotation': - throw new Error(`Any type is not allowed in params for "${arg.name}"`); default: - // TODO (T65847278): Figure out why this does not work. - // (type: empty); + (realTypeAnnotation.type: empty); throw new Error( `Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.type}"`, ); } } -function traverseProperty(property, aliases): string { +function traverseProperty( + property: NativeModulePropertySchema, + resolveAlias: AliasResolver, +): string { const propertyTemplate = property.typeAnnotation.returnTypeAnnotation.type === 'VoidTypeAnnotation' ? voidPropertyTemplate : nonvoidPropertyTemplate; const traversedArgs = property.typeAnnotation.params - .map((p, i) => traverseArg(p, i, aliases)) + .map((p, i) => traverseArg(p, i, resolveAlias)) .join(', '); return propertyTemplate .replace(/::_PROPERTY_NAME_::/g, property.name) @@ -130,23 +147,14 @@ module.exports = { schema: SchemaType, moduleSpecName: string, ): FilesOutput { - const nativeModules = Object.keys(schema.modules) - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, modules) => Object.assign(acc, modules), {}); + const nativeModules = getModules(schema); const modules = Object.keys(nativeModules) .map(name => { const {aliases, properties} = nativeModules[name]; + const resolveAlias = createAliasResolver(aliases); const traversedProperties = properties - .map(property => traverseProperty(property, aliases)) + .map(property => traverseProperty(property, resolveAlias)) .join('\n'); return moduleTemplate .replace(/::_MODULE_PROPERTIES_::/g, traversedProperties) From 4ab7cc236ae2ab11d304f2ebeeee14779bc4ff18 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 28/52] Fix GenerateModuleH Summary: Just updated the generator to work with the new RN Codegen Flow Parser types. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23667252 fbshipit-source-id: 34404a478ddd67446d82b5f98e1051300064e95c --- .../src/generators/modules/GenerateModuleH.js | 57 ++++++++----------- .../GenerateModuleH-test.js.snap | 21 ++++--- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index f2aaa32f41f133..420b6f6a33fa18 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -10,15 +10,10 @@ 'use strict'; -import type { - SchemaType, - FunctionTypeAnnotationParamTypeAnnotation, - FunctionTypeAnnotationReturn, - TypeAliasTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../CodegenSchema'; +import type {SchemaType, NativeModuleTypeAnnotation} from '../../CodegenSchema'; -const {getTypeAliasTypeAnnotation} = require('./Utils'); +import type {AliasResolver} from './Utils'; +const {createAliasResolver, getModules} = require('./Utils'); type FilesOutput = Map; @@ -32,8 +27,9 @@ public: };`; -const template = `/** - * Copyright (c) Facebook, Inc. and its affiliates. +const template = ` +/** + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -54,17 +50,15 @@ namespace react { `; function translatePrimitiveJSTypeToCpp( - typeAnnotation: - | FunctionTypeAnnotationParamTypeAnnotation - | FunctionTypeAnnotationReturn - | TypeAliasTypeAnnotation, + typeAnnotation: NativeModuleTypeAnnotation, createErrorMessage: (typeName: string) => string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, + resolveAlias: AliasResolver, ) { - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; + let realTypeAnnotation = typeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': switch (realTypeAnnotation.name) { @@ -79,6 +73,9 @@ function translatePrimitiveJSTypeToCpp( case 'StringTypeAnnotation': return 'jsi::String'; case 'NumberTypeAnnotation': + return 'double'; + case 'DoubleTypeAnnotation': + return 'double'; case 'FloatTypeAnnotation': return 'double'; case 'Int32TypeAnnotation': @@ -86,6 +83,7 @@ function translatePrimitiveJSTypeToCpp( case 'BooleanTypeAnnotation': return 'bool'; case 'GenericObjectTypeAnnotation': + return 'jsi::Object'; case 'ObjectTypeAnnotation': return 'jsi::Object'; case 'ArrayTypeAnnotation': @@ -95,8 +93,7 @@ function translatePrimitiveJSTypeToCpp( case 'PromiseTypeAnnotation': return 'jsi::Value'; default: - // TODO (T65847278): Figure out why this does not work. - // (type: empty); + (realTypeAnnotation.type: empty); throw new Error(createErrorMessage(realTypeAnnotation.type)); } } @@ -110,21 +107,13 @@ module.exports = { schema: SchemaType, moduleSpecName: string, ): FilesOutput { - const nativeModules = Object.keys(schema.modules) - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, components) => Object.assign(acc, components), {}); + const nativeModules = getModules(schema); const modules = Object.keys(nativeModules) .map(name => { const {aliases, properties} = nativeModules[name]; + const resolveAlias = createAliasResolver(aliases); + const traversedProperties = properties .map(prop => { const traversedArgs = prop.typeAnnotation.params @@ -133,7 +122,7 @@ module.exports = { param.typeAnnotation, typeName => `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, - aliases, + resolveAlias, ); const isObject = translatedParam.startsWith('jsi::'); return ( @@ -151,7 +140,7 @@ module.exports = { prop.typeAnnotation.returnTypeAnnotation, typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`, - aliases, + resolveAlias, ), ) .replace( diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap index fbdcb15bae2c68..4e55a6343121fe 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap @@ -2,7 +2,8 @@ exports[`GenerateModuleH can generate fixture COMPLEX_OBJECTS 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -38,7 +39,8 @@ virtual void getArrays(jsi::Runtime &rt, const jsi::Object &options) = 0; exports[`GenerateModuleH can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -71,7 +73,8 @@ public: exports[`GenerateModuleH can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -105,7 +108,8 @@ virtual void cropImage(jsi::Runtime &rt, const jsi::Object &cropData) = 0; exports[`GenerateModuleH can generate fixture REAL_MODULE_EXAMPLE 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -163,7 +167,8 @@ virtual void dismissRedbox(jsi::Runtime &rt) = 0; exports[`GenerateModuleH can generate fixture SIMPLE_NATIVE_MODULES 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -206,7 +211,8 @@ virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0; exports[`GenerateModuleH can generate fixture TWO_MODULES_DIFFERENT_FILES 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -249,7 +255,8 @@ virtual void voidFunc(jsi::Runtime &rt) = 0; exports[`GenerateModuleH can generate fixture TWO_MODULES_SAME_FILE 1`] = ` Map { - "NativeModules.h" => "/** + "NativeModules.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the From 560ac1a9fac8c0639a5eb3d6778f4913f9ce237a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 29/52] Fix GenerateModuleJavaSpec Summary: Just updated the generator to work with the new RN Codegen Flow Parser types. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23667255 fbshipit-source-id: 40b7747aad89f6d5bbb9f42d59a4df9633060c66 --- .../modules/GenerateModuleJavaSpec.js | 88 +++++++++++-------- .../GenerateModuleJavaSpec-test.js.snap | 33 ++++--- 2 files changed, 72 insertions(+), 49 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 45ff4ba8dcfac7..69958ca41d6950 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -11,18 +11,20 @@ 'use strict'; import type { - FunctionTypeAnnotationParam, - FunctionTypeAnnotationReturn, - NativeModulePropertyShape, - ObjectTypeAliasTypeShape, SchemaType, + NativeModulePropertySchema, + NativeModuleMethodParamSchema, + NativeModuleReturnTypeAnnotation, } from '../../CodegenSchema'; -const {getTypeAliasTypeAnnotation} = require('./Utils'); + +import type {AliasResolver} from './Utils'; +const {createAliasResolver, getModules} = require('./Utils'); type FilesOutput = Map; -const moduleTemplate = `/** - * Copyright (c) Facebook, Inc. and its affiliates. +const moduleTemplate = ` +/** + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root * directory of this source tree. @@ -46,30 +48,32 @@ public abstract class ::_CLASSNAME_:: extends ReactContextBaseJavaModule impleme `; function translateFunctionParamToJavaType( - param: FunctionTypeAnnotationParam, + param: NativeModuleMethodParamSchema, createErrorMessage: (typeName: string) => string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, + resolveAlias: AliasResolver, imports: Set, ): string { - const {nullable, typeAnnotation} = param; + const {optional, typeAnnotation} = param; + const isRequired = !optional && !typeAnnotation.nullable; function wrapIntoNullableIfNeeded(generatedType: string) { - if (nullable) { + if (!isRequired) { imports.add('javax.annotation.Nullable'); return `@Nullable ${generatedType}`; } return generatedType; } - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; + let realTypeAnnotation = typeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': switch (realTypeAnnotation.name) { case 'RootTag': - return nullable ? 'Double' : 'double'; + return !isRequired ? 'Double' : 'double'; default: (realTypeAnnotation.name: empty); throw new Error(createErrorMessage(realTypeAnnotation.name)); @@ -77,11 +81,15 @@ function translateFunctionParamToJavaType( case 'StringTypeAnnotation': return wrapIntoNullableIfNeeded('String'); case 'NumberTypeAnnotation': + return !isRequired ? 'Double' : 'double'; case 'FloatTypeAnnotation': + return !isRequired ? 'Double' : 'double'; + case 'DoubleTypeAnnotation': + return !isRequired ? 'Double' : 'double'; case 'Int32TypeAnnotation': - return nullable ? 'Double' : 'double'; + return !isRequired ? 'Double' : 'double'; case 'BooleanTypeAnnotation': - return nullable ? 'Boolean' : 'boolean'; + return !isRequired ? 'Boolean' : 'boolean'; case 'ObjectTypeAnnotation': imports.add('com.facebook.react.bridge.ReadableMap'); if (typeAnnotation.type === 'TypeAliasTypeAnnotation') { @@ -100,13 +108,15 @@ function translateFunctionParamToJavaType( imports.add('com.facebook.react.bridge.Callback'); return 'Callback'; default: + (realTypeAnnotation.type: empty); throw new Error(createErrorMessage(realTypeAnnotation.type)); } } function translateFunctionReturnTypeToJavaType( - returnTypeAnnotation: FunctionTypeAnnotationReturn, + returnTypeAnnotation: NativeModuleReturnTypeAnnotation, createErrorMessage: (typeName: string) => string, + resolveAlias: AliasResolver, imports: Set, ): string { const {nullable} = returnTypeAnnotation; @@ -119,23 +129,32 @@ function translateFunctionReturnTypeToJavaType( return generatedType; } - // TODO: Support aliased return type. This doesn't exist in React Native Android yet. - switch (returnTypeAnnotation.type) { + let realTypeAnnotation = returnTypeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } + + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (returnTypeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return nullable ? 'Double' : 'double'; default: - (returnTypeAnnotation.name: empty); - throw new Error(createErrorMessage(returnTypeAnnotation.name)); + (realTypeAnnotation.name: empty); + throw new Error(createErrorMessage(realTypeAnnotation.name)); } case 'VoidTypeAnnotation': + return 'void'; case 'PromiseTypeAnnotation': return 'void'; case 'StringTypeAnnotation': return wrapIntoNullableIfNeeded('String'); case 'NumberTypeAnnotation': + return nullable ? 'Double' : 'double'; case 'FloatTypeAnnotation': + return nullable ? 'Double' : 'double'; + case 'DoubleTypeAnnotation': + return nullable ? 'Double' : 'double'; case 'Int32TypeAnnotation': return nullable ? 'Double' : 'double'; case 'BooleanTypeAnnotation': @@ -150,13 +169,14 @@ function translateFunctionReturnTypeToJavaType( imports.add('com.facebook.react.bridge.WritableArray'); return 'WritableArray'; default: - throw new Error(createErrorMessage(returnTypeAnnotation.type)); + (realTypeAnnotation.type: empty); + throw new Error(createErrorMessage(realTypeAnnotation.type)); } } // Build special-cased runtime check for getConstants(). function buildGetConstantsMethod( - method: NativeModulePropertyShape, + method: NativeModulePropertySchema, imports: Set, ): string { if ( @@ -240,20 +260,11 @@ module.exports = { const files = new Map(); // TODO: Allow package configuration. const packageName = 'com.facebook.fbreact.specs.beta'; - const nativeModules = Object.keys(schema.modules) - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, components) => Object.assign(acc, components), {}); + const nativeModules = getModules(schema); Object.keys(nativeModules).forEach(name => { const {aliases, properties} = nativeModules[name]; + const resolveAlias = createAliasResolver(aliases); const className = `Native${name}Spec`; const imports: Set = new Set([ @@ -275,6 +286,7 @@ module.exports = { method.typeAnnotation.returnTypeAnnotation, typeName => `Unsupported return type for method ${method.name}. Found: ${typeName}`, + resolveAlias, imports, ); const returningPromise = @@ -290,7 +302,7 @@ module.exports = { param, typeName => `Unsupported type for param "${param.name}" in ${method.name}. Found: ${typeName}`, - aliases, + resolveAlias, imports, ); return `${translatedParam} ${param.name}`; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap index 13eeb45cc922e6..c9a415a2064dee 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap @@ -2,7 +2,8 @@ exports[`GenerateModuleJavaSpec can generate fixture COMPLEX_OBJECTS 1`] = ` Map { - "NativeSampleTurboModuleSpec.java" => "/** + "NativeSampleTurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -48,7 +49,8 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo exports[`GenerateModuleJavaSpec can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { - "NativeSampleTurboModuleSpec.java" => "/** + "NativeSampleTurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -80,7 +82,8 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo exports[`GenerateModuleJavaSpec can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` Map { - "NativeAliasTurboModuleSpec.java" => "/** + "NativeAliasTurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -114,7 +117,8 @@ public abstract class NativeAliasTurboModuleSpec extends ReactContextBaseJavaMod exports[`GenerateModuleJavaSpec can generate fixture REAL_MODULE_EXAMPLE 1`] = ` Map { - "NativeCameraRollManagerSpec.java" => "/** + "NativeCameraRollManagerSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -151,7 +155,8 @@ public abstract class NativeCameraRollManagerSpec extends ReactContextBaseJavaMo public abstract void deletePhotos(ReadableArray assets, Promise promise); } ", - "NativeImagePickerIOSSpec.java" => "/** + "NativeImagePickerIOSSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -181,7 +186,8 @@ public abstract class NativeImagePickerIOSSpec extends ReactContextBaseJavaModul public abstract void openCameraDialog(ReadableMap config, Callback successCallback, Callback cancelCallback); } ", - "NativeExceptionsManagerSpec.java" => "/** + "NativeExceptionsManagerSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -228,7 +234,8 @@ public abstract class NativeExceptionsManagerSpec extends ReactContextBaseJavaMo exports[`GenerateModuleJavaSpec can generate fixture SIMPLE_NATIVE_MODULES 1`] = ` Map { - "NativeSampleTurboModuleSpec.java" => "/** + "NativeSampleTurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -327,7 +334,8 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo exports[`GenerateModuleJavaSpec can generate fixture TWO_MODULES_DIFFERENT_FILES 1`] = ` Map { - "NativeSampleTurboModuleSpec.java" => "/** + "NativeSampleTurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -355,7 +363,8 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo public abstract void voidFunc(); } ", - "NativeSample2TurboModuleSpec.java" => "/** + "NativeSample2TurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -388,7 +397,8 @@ public abstract class NativeSample2TurboModuleSpec extends ReactContextBaseJavaM exports[`GenerateModuleJavaSpec can generate fixture TWO_MODULES_SAME_FILE 1`] = ` Map { - "NativeSampleTurboModuleSpec.java" => "/** + "NativeSampleTurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root @@ -416,7 +426,8 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo public abstract void voidFunc(); } ", - "NativeSample2TurboModuleSpec.java" => "/** + "NativeSample2TurboModuleSpec.java" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the LICENSE file in the root From cedd628fc32714d87ad9dae41f083e5e431bb6e7 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 30/52] Fix GenerateModuleJniH Summary: Just updated the generator to work with the new RN Codegen Flow Parser types. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D23667250 fbshipit-source-id: f36b5418101c40331964d1f9ede7c6bd7924383d --- .../generators/modules/GenerateModuleJniH.js | 21 ++++-------- .../GenerateModuleJniH-test.js.snap | 33 +++++++++++-------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js index 4d9a5aac0cf688..18dde67c9b1297 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js @@ -14,6 +14,8 @@ import type {SchemaType} from '../../CodegenSchema'; type FilesOutput = Map; +const {getModules} = require('./Utils'); + const moduleTemplate = `/** * JNI C++ class for module '::_MODULE_NAME_::' */ @@ -23,8 +25,9 @@ public: }; `; -const template = `/** - * Copyright (c) Facebook, Inc. and its affiliates. +const template = ` +/** + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -84,19 +87,7 @@ module.exports = { schema: SchemaType, moduleSpecName: string, ): FilesOutput { - const nativeModules = Object.keys(schema.modules) - .sort() - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, components) => Object.assign(acc, components), {}); - + const nativeModules = getModules(schema); const modules = Object.keys(nativeModules) .map(name => moduleTemplate.replace(/::_MODULE_NAME_::/g, name)) .join('\n'); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap index efe08283828084..64cbc779b30315 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap @@ -2,7 +2,8 @@ exports[`GenerateModuleJniH can generate fixture COMPLEX_OBJECTS 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -67,7 +68,8 @@ include $(BUILD_SHARED_LIBRARY) exports[`GenerateModuleJniH can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -132,7 +134,8 @@ include $(BUILD_SHARED_LIBRARY) exports[`GenerateModuleJniH can generate fixture NATIVE_MODULES_WITH_TYPE_ALIASES 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -197,7 +200,8 @@ include $(BUILD_SHARED_LIBRARY) exports[`GenerateModuleJniH can generate fixture REAL_MODULE_EXAMPLE 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -224,19 +228,19 @@ public: }; /** - * JNI C++ class for module 'ExceptionsManager' + * JNI C++ class for module 'ImagePickerIOS' */ -class JSI_EXPORT NativeExceptionsManagerSpecJSI : public JavaTurboModule { +class JSI_EXPORT NativeImagePickerIOSSpecJSI : public JavaTurboModule { public: - NativeExceptionsManagerSpecJSI(const JavaTurboModule::InitParams ¶ms); + NativeImagePickerIOSSpecJSI(const JavaTurboModule::InitParams ¶ms); }; /** - * JNI C++ class for module 'ImagePickerIOS' + * JNI C++ class for module 'ExceptionsManager' */ -class JSI_EXPORT NativeImagePickerIOSSpecJSI : public JavaTurboModule { +class JSI_EXPORT NativeExceptionsManagerSpecJSI : public JavaTurboModule { public: - NativeImagePickerIOSSpecJSI(const JavaTurboModule::InitParams ¶ms); + NativeExceptionsManagerSpecJSI(const JavaTurboModule::InitParams ¶ms); }; @@ -278,7 +282,8 @@ include $(BUILD_SHARED_LIBRARY) exports[`GenerateModuleJniH can generate fixture SIMPLE_NATIVE_MODULES 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -343,7 +348,8 @@ include $(BUILD_SHARED_LIBRARY) exports[`GenerateModuleJniH can generate fixture TWO_MODULES_DIFFERENT_FILES 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the @@ -416,7 +422,8 @@ include $(BUILD_SHARED_LIBRARY) exports[`GenerateModuleJniH can generate fixture TWO_MODULES_SAME_FILE 1`] = ` Map { - "SampleSpec.h" => "/** + "SampleSpec.h" => " +/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the From 1b3dc1d9e32a4596a3a2cf5d476cfc5176fe7203 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 31/52] Fix GenerateModuleJniCpp Summary: Just updated the generator to work with the new RN Codegen Flow Parser types. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D23667253 fbshipit-source-id: ef94e75287d37dfd7b80f61455a1bfa34bddeb28 --- .../modules/GenerateModuleJniCpp.js | 138 ++++++++++-------- 1 file changed, 80 insertions(+), 58 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js index a97083d86bd7f3..72b48a7fcdab72 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniCpp.js @@ -11,14 +11,14 @@ 'use strict'; import type { - FunctionTypeAnnotationParam, - FunctionTypeAnnotationReturn, - NativeModuleShape, - ObjectTypeAliasTypeShape, SchemaType, + NativeModulePropertySchema, + NativeModuleMethodParamSchema, + NativeModuleReturnTypeAnnotation, } from '../../CodegenSchema'; -const {getTypeAliasTypeAnnotation} = require('./Utils'); +import type {AliasResolver} from './Utils'; +const {createAliasResolver, getModules} = require('./Utils'); type FilesOutput = Map; @@ -50,7 +50,7 @@ const oneModuleLookupTemplate = ` if (moduleName == "::_MODULE_NAME_::") { const template = ` /** - * Copyright (c) Facebook, Inc. and its affiliates. + * ${'C'}opyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -75,17 +75,23 @@ std::shared_ptr ::_LIBRARY_NAME_::_ModuleProvider(const std::string `; function translateReturnTypeToKind( - typeAnnotation: FunctionTypeAnnotationReturn, + typeAnnotation: NativeModuleReturnTypeAnnotation, + resolveAlias: AliasResolver, ): string { - switch (typeAnnotation.type) { + let realTypeAnnotation = typeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } + + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': return 'NumberKind'; default: - (typeAnnotation.name: empty); + (realTypeAnnotation.name: empty); throw new Error( - `Invalid ReservedFunctionValueTypeName name, got ${typeAnnotation.name}`, + `Invalid ReservedFunctionValueTypeName name, got ${realTypeAnnotation.name}`, ); } case 'VoidTypeAnnotation': @@ -95,62 +101,66 @@ function translateReturnTypeToKind( case 'BooleanTypeAnnotation': return 'BooleanKind'; case 'NumberTypeAnnotation': + return 'NumberKind'; case 'DoubleTypeAnnotation': + return 'NumberKind'; case 'FloatTypeAnnotation': + return 'NumberKind'; case 'Int32TypeAnnotation': return 'NumberKind'; case 'PromiseTypeAnnotation': return 'PromiseKind'; case 'GenericObjectTypeAnnotation': + return 'ObjectKind'; case 'ObjectTypeAnnotation': return 'ObjectKind'; case 'ArrayTypeAnnotation': return 'ArrayKind'; default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); + (realTypeAnnotation.type: empty); throw new Error( - `Unknown prop type for returning value, found: ${typeAnnotation.type}"`, + `Unknown prop type for returning value, found: ${realTypeAnnotation.type}"`, ); } } function translateParamTypeToJniType( - param: FunctionTypeAnnotationParam, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, + param: NativeModuleMethodParamSchema, + resolveAlias: AliasResolver, ): string { - const {nullable, typeAnnotation} = param; + const {optional, typeAnnotation} = param; + const isRequired = !optional && !typeAnnotation.nullable; - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; + let realTypeAnnotation = typeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': switch (realTypeAnnotation.name) { case 'RootTag': - return 'D'; + return !isRequired ? 'Ljava/lang/Double;' : 'D'; default: (realTypeAnnotation.name: empty); throw new Error( `Invalid ReservedFunctionValueTypeName name, got ${realTypeAnnotation.name}`, ); } - case 'VoidTypeAnnotation': - return 'V'; case 'StringTypeAnnotation': return 'Ljava/lang/String;'; case 'BooleanTypeAnnotation': - return nullable ? 'Ljava/lang/Boolean' : 'Z'; + return !isRequired ? 'Ljava/lang/Boolean' : 'Z'; case 'NumberTypeAnnotation': + return !isRequired ? 'Ljava/lang/Double;' : 'D'; case 'DoubleTypeAnnotation': + return !isRequired ? 'Ljava/lang/Double;' : 'D'; case 'FloatTypeAnnotation': + return !isRequired ? 'Ljava/lang/Double;' : 'D'; case 'Int32TypeAnnotation': - return nullable ? 'Ljava/lang/Double;' : 'D'; - case 'PromiseTypeAnnotation': - return 'Lcom/facebook/react/bridge/Promise;'; + return !isRequired ? 'Ljava/lang/Double;' : 'D'; case 'GenericObjectTypeAnnotation': + return 'Lcom/facebook/react/bridge/ReadableMap;'; case 'ObjectTypeAnnotation': return 'Lcom/facebook/react/bridge/ReadableMap;'; case 'ArrayTypeAnnotation': @@ -158,6 +168,7 @@ function translateParamTypeToJniType( case 'FunctionTypeAnnotation': return 'Lcom/facebook/react/bridge/Callback;'; default: + (realTypeAnnotation.type: empty); throw new Error( `Unknown prop type for method arg, found: ${realTypeAnnotation.type}"`, ); @@ -165,19 +176,25 @@ function translateParamTypeToJniType( } function translateReturnTypeToJniType( - typeAnnotation: FunctionTypeAnnotationReturn, + typeAnnotation: NativeModuleReturnTypeAnnotation, + resolveAlias: AliasResolver, ): string { const {nullable} = typeAnnotation; - switch (typeAnnotation.type) { + let realTypeAnnotation = typeAnnotation; + if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + realTypeAnnotation = resolveAlias(realTypeAnnotation.name); + } + + switch (realTypeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { + switch (realTypeAnnotation.name) { case 'RootTag': - return 'D'; + return nullable ? 'Ljava/lang/Double;' : 'D'; default: - (typeAnnotation.name: empty); + (realTypeAnnotation.name: empty); throw new Error( - `Invalid ReservedFunctionValueTypeName name, got ${typeAnnotation.name}`, + `Invalid ReservedFunctionValueTypeName name, got ${realTypeAnnotation.name}`, ); } case 'VoidTypeAnnotation': @@ -187,27 +204,32 @@ function translateReturnTypeToJniType( case 'BooleanTypeAnnotation': return nullable ? 'Ljava/lang/Boolean' : 'Z'; case 'NumberTypeAnnotation': + return nullable ? 'Ljava/lang/Double;' : 'D'; case 'DoubleTypeAnnotation': + return nullable ? 'Ljava/lang/Double;' : 'D'; case 'FloatTypeAnnotation': + return nullable ? 'Ljava/lang/Double;' : 'D'; case 'Int32TypeAnnotation': return nullable ? 'Ljava/lang/Double;' : 'D'; case 'PromiseTypeAnnotation': return 'Lcom/facebook/react/bridge/Promise;'; case 'GenericObjectTypeAnnotation': + return 'Lcom/facebook/react/bridge/WritableMap;'; case 'ObjectTypeAnnotation': return 'Lcom/facebook/react/bridge/WritableMap;'; case 'ArrayTypeAnnotation': return 'Lcom/facebook/react/bridge/WritableArray;'; default: + (realTypeAnnotation.type: empty); throw new Error( - `Unknown prop type for method return type, found: ${typeAnnotation.type}"`, + `Unknown prop type for method return type, found: ${realTypeAnnotation.type}"`, ); } } function translateMethodTypeToJniSignature( - property, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, + property: NativeModulePropertySchema, + resolveAlias: AliasResolver, ): string { const {name, typeAnnotation} = property; const {returnTypeAnnotation} = typeAnnotation; @@ -223,24 +245,29 @@ function translateMethodTypeToJniSignature( } const argsSignatureParts = params.map(t => { - return translateParamTypeToJniType(t, aliases); + return translateParamTypeToJniType(t, resolveAlias); }); if (isPromiseReturn) { // Additional promise arg for this case. - argsSignatureParts.push(translateReturnTypeToJniType(returnTypeAnnotation)); + argsSignatureParts.push( + translateReturnTypeToJniType(returnTypeAnnotation, resolveAlias), + ); } const argsSignature = argsSignatureParts.join(''); const returnSignature = name === 'getConstants' ? 'Ljava/util/Map;' - : translateReturnTypeToJniType(processedReturnTypeAnnotation); + : translateReturnTypeToJniType( + processedReturnTypeAnnotation, + resolveAlias, + ); return `(${argsSignature})${returnSignature}`; } function translateMethodForImplementation( - property, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, + property: NativeModulePropertySchema, + resolveAlias: AliasResolver, ): string { const {returnTypeAnnotation} = property.typeAnnotation; @@ -264,7 +291,10 @@ function translateMethodForImplementation( return ''; } return propertyTemplate - .replace(/::_KIND_::/g, translateReturnTypeToKind(returnTypeAnnotation)) + .replace( + /::_KIND_::/g, + translateReturnTypeToKind(returnTypeAnnotation, resolveAlias), + ) .replace(/::_PROPERTY_NAME_::/g, property.name) .replace( /::_ARGS_::/g, @@ -274,7 +304,7 @@ function translateMethodForImplementation( ) .replace( /::_SIGNATURE_::/g, - translateMethodTypeToJniSignature(property, aliases), + translateMethodTypeToJniSignature(property, resolveAlias), ); } @@ -284,25 +314,17 @@ module.exports = { schema: SchemaType, moduleSpecName: string, ): FilesOutput { - const nativeModules: {[name: string]: NativeModuleShape, ...} = Object.keys( - schema.modules, - ) - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, modules) => Object.assign(acc, modules), {}); + const nativeModules = getModules(schema); const modules = Object.keys(nativeModules) .map(name => { const {aliases, properties} = nativeModules[name]; + const resolveAlias = createAliasResolver(aliases); + const translatedMethods = properties - .map(property => translateMethodForImplementation(property, aliases)) + .map(property => + translateMethodForImplementation(property, resolveAlias), + ) .join('\n'); return moduleTemplate .replace(/::_TURBOMODULE_METHOD_INVOKERS_::/g, translatedMethods) From 97d3e85c294913af4ab21b4bf8343c2839313b4c Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 32/52] Fix ObjC++ module generator output Summary: * Removed extraneous closing brace. * Fixed static method signature, replacing double colon with an underscore (`static facebook::jsi::Value __hostFunction_Native${moduleName}SpecJSI::${methodName}()` -> `static facebook::jsi::Value __hostFunction_Native${moduleName}SpecJSI_${methodName}()`). * Wrap `getConstants` selector name with `selector()`. * Pass through `getConstants` and `constantsToExport` to allow de-duping of `getConstants` method in generator output. Note that the FBReactNativeSpec that is output by the generator still has some issues that need to be addressed before it can be used. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D23910505 fbshipit-source-id: 37d884885b8878f38d40637377c2a74a728c3a13 --- .../GenerateModuleObjCpp-test.js.snap | 271 +++++++----------- .../modules/GenerateModuleObjCpp/index.js | 2 +- .../GenerateModuleObjCpp/serializeMethod.js | 4 +- .../source/serializeModule.js | 3 +- .../GenerateModuleMm-test.js.snap | 80 ++---- 5 files changed, 131 insertions(+), 229 deletions(-) diff --git a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap index 73bfce8a865d1b..84e76d76df8679 100644 --- a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap @@ -1320,17 +1320,17 @@ exports[`GenerateModuleObjCpp can generate an implementation file NativeModule s namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI::getReadOnlyArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI_getReadOnlyArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getReadOnlyArray\\", @selector(getReadOnlyArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI::getArrayWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeArrayTurboModuleSpecJSI_getArrayWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArrayWithAlias\\", @selector(getArrayWithAlias:b:), args, count); } @@ -1349,7 +1349,6 @@ namespace facebook { methodMap_[\\"getArrayWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeArrayTurboModuleSpecJSI_getArrayWithAlias}; - } } } // namespace react } // namespace facebook @@ -1359,12 +1358,12 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeBooleanTurboModuleSpecJSI::getBoolean(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeBooleanTurboModuleSpecJSI_getBoolean(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBoolean\\", @selector(getBoolean:), args, count); } - static facebook::jsi::Value __hostFunction_NativeBooleanTurboModuleSpecJSI::getBooleanWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeBooleanTurboModuleSpecJSI_getBooleanWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBooleanWithAlias\\", @selector(getBooleanWithAlias:), args, count); } @@ -1379,7 +1378,6 @@ namespace facebook { methodMap_[\\"getBooleanWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeBooleanTurboModuleSpecJSI_getBooleanWithAlias}; - } } } // namespace react } // namespace facebook @@ -1389,12 +1387,12 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeCallbackTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeCallbackTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeCallbackTurboModuleSpecJSI::getValueWithCallbackWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeCallbackTurboModuleSpecJSI_getValueWithCallbackWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallbackWithAlias\\", @selector(getValueWithCallbackWithAlias:), args, count); } @@ -1409,7 +1407,6 @@ namespace facebook { methodMap_[\\"getValueWithCallbackWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeCallbackTurboModuleSpecJSI_getValueWithCallbackWithAlias}; - } } } // namespace react } // namespace facebook @@ -1419,32 +1416,32 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNullableTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:reject:), args, count); } @@ -1475,7 +1472,6 @@ namespace facebook { methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getValueWithPromise}; - } } } // namespace react } // namespace facebook @@ -1485,12 +1481,12 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeNumberTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNumberTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeNumberTurboModuleSpecJSI::getNumberWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeNumberTurboModuleSpecJSI_getNumberWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumberWithAlias\\", @selector(getNumberWithAlias:), args, count); } @@ -1505,7 +1501,6 @@ namespace facebook { methodMap_[\\"getNumberWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeNumberTurboModuleSpecJSI_getNumberWithAlias}; - } } } // namespace react } // namespace facebook @@ -1562,33 +1557,28 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getGenericObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI_getGenericObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getGenericObject\\", @selector(getGenericObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getGenericObjectReadOnly(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI_getGenericObjectReadOnly(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getGenericObjectReadOnly\\", @selector(getGenericObjectReadOnly:), args, count); } - static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getGenericObjectWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI_getGenericObjectWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getGenericObjectWithAlias\\", @selector(getGenericObjectWithAlias:), args, count); } - static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::difficultObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI_difficultObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"difficultObject\\", @selector(difficultObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -1614,11 +1604,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -1659,13 +1644,8 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeOptionalObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeOptionalObjectTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -1675,11 +1655,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -1689,12 +1664,12 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativePromiseTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativePromiseTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativePromiseTurboModuleSpecJSI::getValueWithPromiseWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativePromiseTurboModuleSpecJSI_getValueWithPromiseWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromiseWithAlias\\", @selector(getValueWithPromiseWithAlias:resolve:reject:), args, count); } @@ -1709,7 +1684,6 @@ namespace facebook { methodMap_[\\"getValueWithPromiseWithAlias\\"] = MethodMetadata {1, __hostFunction_NativePromiseTurboModuleSpecJSI_getValueWithPromiseWithAlias}; - } } } // namespace react } // namespace facebook @@ -1742,73 +1716,68 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:getValuegetValuegetValuegetValuegetValuey:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -1866,11 +1835,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -1895,73 +1859,68 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getAlias\\", @selector(getAlias:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -2019,11 +1978,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -2056,73 +2010,68 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -2180,11 +2129,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -2217,73 +2161,68 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -2341,11 +2280,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -2378,73 +2312,68 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getObjectShape(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObjectShape\\", @selector(getObjectShape:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getAlias\\", @selector(getAlias:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -2502,11 +2431,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -2516,12 +2440,12 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeStringTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeStringTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeStringTurboModuleSpecJSI::getStringWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeStringTurboModuleSpecJSI_getStringWithAlias(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getStringWithAlias\\", @selector(getStringWithAlias:), args, count); } @@ -2536,7 +2460,6 @@ namespace facebook { methodMap_[\\"getStringWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeStringTurboModuleSpecJSI_getStringWithAlias}; - } } } // namespace react } // namespace facebook diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js index 0f1852415b206c..ee2d5e1e42d375 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js @@ -184,7 +184,7 @@ module.exports = { moduleName, generatedStructs, methodSerializations.filter( - ({selector}) => selector !== 'constantsToExport', + ({selector}) => selector !== '@selector(constantsToExport)', ), ), ); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js index 6fe0c47b288e9a..46f77f64437f3e 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -398,10 +398,10 @@ function serializeConstantsProtocolMethods( }); return { - methodName: 'getConstants', + methodName, protocolMethod, returnJSType: 'ObjectKind', - selector: 'getConstants', + selector: `@selector(${methodName})`, structParamRecords: [], }; }, diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js index 82c69359a06d36..d45f296eadef38 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js @@ -54,7 +54,6 @@ namespace facebook { }), ) .join('\n' + ' '.repeat(8))} - } } } // namespace react } // namespace facebook @@ -86,7 +85,7 @@ const InlineHostFunctionTemplate = ({ returnJSType: string, selector: string, |}>) => ` - static facebook::jsi::Value __hostFunction_Native${moduleName}SpecJSI::${methodName}(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_Native${moduleName}SpecJSI_${methodName}(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ${returnJSType}, "${methodName}", ${selector}, args, count); } `; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index 1d9e6034f4baeb..e39700023e3b19 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -70,22 +70,22 @@ Map { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"difficult\\", @selector(difficult:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"optionals\\", @selector(optionals:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"optionalMethod\\", @selector(optionalMethod:callback:extras:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArrays(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getArrays\\", @selector(getArrays:), args, count); } @@ -108,7 +108,6 @@ namespace facebook { methodMap_[\\"getArrays\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays}; setMethodArgConversionSelector(@\\"getArrays\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetArraysOptions:\\"); - } } } // namespace react } // namespace facebook @@ -144,7 +143,6 @@ namespace facebook { NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - } } } // namespace react } // namespace facebook @@ -207,7 +205,7 @@ Map { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI::cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count); } @@ -218,7 +216,6 @@ namespace facebook { methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_SpecCropImageCropData:\\"); - } } } // namespace react } // namespace facebook @@ -257,17 +254,17 @@ Map { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count); } @@ -286,7 +283,6 @@ namespace facebook { methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos}; - } } } // namespace react } // namespace facebook @@ -311,27 +307,27 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count); } @@ -358,7 +354,6 @@ namespace facebook { methodMap_[\\"dismissRedbox\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; - } } } // namespace react } // namespace facebook @@ -375,7 +370,7 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI::openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count); } @@ -386,7 +381,6 @@ namespace facebook { methodMap_[\\"openCameraDialog\\"] = MethodMetadata {1, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); - } } } // namespace react } // namespace facebook @@ -425,63 +419,58 @@ Map { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); - } - - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); } @@ -531,11 +520,6 @@ namespace facebook { methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - - - } } } // namespace react } // namespace facebook @@ -567,7 +551,7 @@ Map { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } @@ -578,7 +562,6 @@ namespace facebook { methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; - } } } // namespace react } // namespace facebook @@ -588,7 +571,7 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } @@ -599,7 +582,6 @@ namespace facebook { methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - } } } // namespace react } // namespace facebook @@ -631,7 +613,7 @@ Map { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } @@ -642,7 +624,6 @@ namespace facebook { methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; - } } } // namespace react } // namespace facebook @@ -652,7 +633,7 @@ namespace facebook { namespace facebook { namespace react { - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } @@ -663,7 +644,6 @@ namespace facebook { methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - } } } // namespace react } // namespace facebook From 6d6e04619fff66a255f41a7592d43f065068a75a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 33/52] Fix ObjC++ structs and method mapping Summary: Adjust generated ObjC++ code to resolve a few build time and run time errors: * Suppress CONSTANTS struct implementations * Use type alias name as struct name when serializing arguments that involve a type alias * Use actual number of arguments for a method when generating method map. With these changes in place, RNTester can be built and run using the code that is generated by the new codegen. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23926500 fbshipit-source-id: 88fcbb795fd71dc8155eb26348db943975e13e84 --- .../GenerateModuleObjCpp-test.js.snap | 156 +++--------------- .../GenerateModuleObjCpp/serializeMethod.js | 16 +- .../source/serializeModule.js | 9 +- .../GenerateModuleMm-test.js.snap | 41 ++--- 4 files changed, 61 insertions(+), 161 deletions(-) diff --git a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap index 84e76d76df8679..c0df45acc209bc 100644 --- a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap @@ -1346,7 +1346,7 @@ namespace facebook { - methodMap_[\\"getArrayWithAlias\\"] = MethodMetadata {1, __hostFunction_NativeArrayTurboModuleSpecJSI_getArrayWithAlias}; + methodMap_[\\"getArrayWithAlias\\"] = MethodMetadata {2, __hostFunction_NativeArrayTurboModuleSpecJSI_getArrayWithAlias}; } @@ -1469,7 +1469,7 @@ namespace facebook { - methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeNullableTurboModuleSpecJSI_getValueWithPromise}; + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {0, __hostFunction_NativeNullableTurboModuleSpecJSI_getValueWithPromise}; } @@ -1522,38 +1522,6 @@ namespace facebook { } @end - -@implementation RCTCxxConvert (NativeObjectTurboModule_ConstantsEEE) -+ (RCTManagedPointer *)JS_NativeObjectTurboModule_ConstantsEEE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeObjectTurboModule_ConstantsEE) -+ (RCTManagedPointer *)JS_NativeObjectTurboModule_ConstantsEE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeObjectTurboModule_ConstantsE) -+ (RCTManagedPointer *)JS_NativeObjectTurboModule_ConstantsE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeObjectTurboModule_Constants) -+ (RCTManagedPointer *)JS_NativeObjectTurboModule_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -1601,7 +1569,7 @@ namespace facebook { setMethodArgConversionSelector(@\\"difficultObject\\", 0, @\\"JS_NativeObjectTurboModule_SpecDifficultObjectA:\\"); - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeObjectTurboModuleSpecJSI_getConstants}; } @@ -1610,37 +1578,6 @@ namespace facebook { -@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_ConstantsEEE) -+ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_ConstantsEEE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_ConstantsEE) -+ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_ConstantsEE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_ConstantsE) -+ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_ConstantsE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeOptionalObjectTurboModule_Constants) -+ (RCTManagedPointer *)JS_NativeOptionalObjectTurboModule_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -1652,7 +1589,7 @@ namespace facebook { NativeOptionalObjectTurboModuleSpecJSI::NativeOptionalObjectTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeOptionalObjectTurboModuleSpecJSI_getConstants}; } @@ -1705,14 +1642,6 @@ namespace facebook { } @end - -@implementation RCTCxxConvert (NativeSampleTurboModule_Constants) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -1784,7 +1713,7 @@ namespace facebook { NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; @@ -1813,14 +1742,14 @@ namespace facebook { methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getAlias}; - setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetAliasArg:\\"); + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModule_Animal:\\"); methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; @@ -1832,7 +1761,7 @@ namespace facebook { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; } @@ -1841,21 +1770,6 @@ namespace facebook { -@implementation RCTCxxConvert (NativeSampleTurboModuleArrays_ConstantsIdElement) -+ (RCTManagedPointer *)JS_NativeSampleTurboModuleArrays_ConstantsIdElement:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeSampleTurboModuleArrays_Constants) -+ (RCTManagedPointer *)JS_NativeSampleTurboModuleArrays_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -1927,7 +1841,7 @@ namespace facebook { NativeSampleTurboModuleArraysSpecJSI::NativeSampleTurboModuleArraysSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_voidFunc}; @@ -1963,7 +1877,7 @@ namespace facebook { - methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValue}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getValue}; @@ -1975,7 +1889,7 @@ namespace facebook { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleArraysSpecJSI_getConstants}; } @@ -1999,14 +1913,6 @@ namespace facebook { } @end - -@implementation RCTCxxConvert (NativeSampleTurboModuleNullable_Constants) -+ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullable_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -2078,7 +1984,7 @@ namespace facebook { NativeSampleTurboModuleNullableSpecJSI::NativeSampleTurboModuleNullableSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_voidFunc}; @@ -2107,14 +2013,14 @@ namespace facebook { methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getAlias}; - setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleNullable_SpecGetAliasArg:\\"); + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleNullable_Animal:\\"); methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValue}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getValue}; @@ -2126,7 +2032,7 @@ namespace facebook { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleNullableSpecJSI_getConstants}; } @@ -2150,14 +2056,6 @@ namespace facebook { } @end - -@implementation RCTCxxConvert (NativeSampleTurboModuleNullableAndOptional_Constants) -+ (RCTManagedPointer *)JS_NativeSampleTurboModuleNullableAndOptional_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -2229,7 +2127,7 @@ namespace facebook { NativeSampleTurboModuleNullableAndOptionalSpecJSI::NativeSampleTurboModuleNullableAndOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_voidFunc}; @@ -2258,14 +2156,14 @@ namespace facebook { methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getAlias}; - setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleNullableAndOptional_SpecGetAliasArg:\\"); + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleNullableAndOptional_Animal:\\"); methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValue}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getValue}; @@ -2277,7 +2175,7 @@ namespace facebook { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleNullableAndOptionalSpecJSI_getConstants}; } @@ -2301,14 +2199,6 @@ namespace facebook { } @end - -@implementation RCTCxxConvert (NativeSampleTurboModuleOptional_Constants) -+ (RCTManagedPointer *)JS_NativeSampleTurboModuleOptional_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -2380,7 +2270,7 @@ namespace facebook { NativeSampleTurboModuleOptionalSpecJSI::NativeSampleTurboModuleOptionalSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_voidFunc}; @@ -2409,14 +2299,14 @@ namespace facebook { methodMap_[\\"getAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getAlias}; - setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleOptional_SpecGetAliasArg:\\"); + setMethodArgConversionSelector(@\\"getAlias\\", 0, @\\"JS_NativeSampleTurboModuleOptional_Animal:\\"); methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValue}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getValue}; @@ -2428,7 +2318,7 @@ namespace facebook { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleOptionalSpecJSI_getConstants}; } diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js index 46f77f64437f3e..bec84f59d6de76 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -51,6 +51,7 @@ export type MethodSerializationOutput = $ReadOnly<{| selector: string, structParamRecords: $ReadOnlyArray, returnJSType: ReturnJSType, + argCount: number, |}>; function serializeMethod( @@ -77,7 +78,7 @@ function serializeMethod( const structParamRecords: Array = []; params.forEach((param, index) => { - const structName = `Spec${capitalize(methodName)}${capitalize(param.name)}`; + const structName = getParamStructName(methodName, param); const {objCType, isStruct} = getParamObjCType( moduleName, methodName, @@ -145,10 +146,22 @@ function serializeMethod( selector: `@selector(${selector})`, structParamRecords, returnJSType, + argCount: params.length, }, ]; } +function getParamStructName( + methodName: string, + param: NativeModuleMethodParamSchema, +): string { + if (param.typeAnnotation.type === 'TypeAliasTypeAnnotation') { + return param.typeAnnotation.name; + } + + return `Spec${capitalize(methodName)}${capitalize(param.name)}`; +} + function getParamObjCType( moduleName: string, methodName: string, @@ -403,6 +416,7 @@ function serializeConstantsProtocolMethods( returnJSType: 'ObjectKind', selector: `@selector(${methodName})`, structParamRecords: [], + argCount: 0, }; }, ); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js index d45f296eadef38..72013475009fbe 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js @@ -46,11 +46,12 @@ namespace facebook { Native${moduleName}SpecJSI::Native${moduleName}SpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { ${methodSerializationOutputs - .map(({methodName, structParamRecords}) => + .map(({methodName, structParamRecords, argCount}) => MethodMapEntryTemplate({ moduleName, methodName, structParamRecords, + argCount, }), ) .join('\n' + ' '.repeat(8))} @@ -94,12 +95,14 @@ const MethodMapEntryTemplate = ({ moduleName, methodName, structParamRecords, + argCount, }: $ReadOnly<{| moduleName: string, methodName: string, structParamRecords: $ReadOnlyArray, + argCount: number, |}>) => ` - methodMap_["${methodName}"] = MethodMetadata {1, __hostFunction_Native${moduleName}SpecJSI_${methodName}}; + methodMap_["${methodName}"] = MethodMetadata {${argCount}, __hostFunction_Native${moduleName}SpecJSI_${methodName}}; ${structParamRecords .map(({paramIndex, structName}) => { return `setMethodArgConversionSelector(@"${methodName}", ${paramIndex}, @"JS_Native${moduleName}_${structName}:");`; @@ -114,7 +117,7 @@ function serializeModuleSource( ): string { return ModuleTemplate({ moduleName, - structs, + structs: structs.filter(({context}) => context !== 'CONSTANTS'), methodSerializationOutputs, }); } diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index e39700023e3b19..53e98c9fdf939a 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -101,7 +101,7 @@ namespace facebook { setMethodArgConversionSelector(@\\"optionals\\", 0, @\\"JS_NativeSampleTurboModule_SpecOptionalsA:\\"); - methodMap_[\\"optionalMethod\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; + methodMap_[\\"optionalMethod\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; @@ -214,7 +214,7 @@ namespace facebook { : ObjCTurboModule(params) { methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; - setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_SpecCropImageCropData:\\"); + setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_Options:\\"); } } // namespace react @@ -273,10 +273,10 @@ namespace facebook { : ObjCTurboModule(params) { methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; - setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_SpecGetPhotosParams:\\"); + setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_GetPhotosParams:\\"); - methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; + methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; @@ -335,23 +335,23 @@ namespace facebook { NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"reportFatalException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; + methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; - methodMap_[\\"reportSoftException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; + methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException}; - setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_SpecReportExceptionData:\\"); + setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_ExceptionData:\\"); - methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; + methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; - methodMap_[\\"dismissRedbox\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; + methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; } @@ -378,7 +378,7 @@ namespace facebook { NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"openCameraDialog\\"] = MethodMetadata {1, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; + methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); } @@ -409,13 +409,6 @@ Map { -@implementation RCTCxxConvert (NativeSampleTurboModule_Constants) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_Constants:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - namespace facebook { namespace react { @@ -477,7 +470,7 @@ namespace facebook { NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; @@ -505,7 +498,7 @@ namespace facebook { - methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; @@ -517,7 +510,7 @@ namespace facebook { - methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; } @@ -559,7 +552,7 @@ namespace facebook { NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; } @@ -579,7 +572,7 @@ namespace facebook { NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; } @@ -621,7 +614,7 @@ namespace facebook { NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; } @@ -641,7 +634,7 @@ namespace facebook { NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; } From 6e6443afd04a847ef23fb6254a84e48c70b45896 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH 34/52] Remove header_namespace from module codegen target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Making this change because I see this error when compiling Internationalization ``` ➜ fbsource buck build //xplat/js/RKJSModules/Libraries/Internationalization:generated_objcpp_modules-InternationalizationApple buck-out/gen/33fbdb84/xplat/js/RKJSModules/Libraries/Internationalization/generate_module_mm-Internationalization/FBReactNativeInternationalizationSpec-generated.mm:15:9: fatal error: 'FBReactNativeInternationalizationSpec.h' file not found #import "FBReactNativeInternationalizationSpec.h" ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. Command failed with exit code 1. command: [/Applications/Xcode_11.6.0_fb.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++, @/Users/ramanpreet/fbsource/buck-out/bin/33fbdb84/xplat/js/RKJSModules/Libraries/Internationalization/generated_objcpp_modules-InternationalizationApple#compile-FBReactNativeInternationalizationSpec-generated.mm.o... ``` Since the header namespace is "FBReactNativeInternationalizationSpec", we can only import the header file via "FBReactNativeInternationalizationSpec/FBReactNativeInternationalizationSpec.h", according to this buck documentation: https://buck.build/rule/cxx_library.html#headers. Not entirely sure how this target compiled before. The legacy codegen buck target also set the header namespace to "": https://fburl.com/diffusion/3p85qhf9. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23978436 fbshipit-source-id: c9cd7c710edf94df6df10778f8603870f92275a7 --- packages/react-native-codegen/DEFS.bzl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-native-codegen/DEFS.bzl b/packages/react-native-codegen/DEFS.bzl index 33abd24eeaffe5..4da9f3c420c39e 100644 --- a/packages/react-native-codegen/DEFS.bzl +++ b/packages/react-native-codegen/DEFS.bzl @@ -50,7 +50,7 @@ def rn_codegen_modules( rn_xplat_cxx_library( name = "generated_objcpp_modules-{}".format(name), - header_namespace = native_module_spec_name, + header_namespace = "", apple_sdks = (IOS), compiler_flags = [ "-fexceptions", @@ -61,8 +61,7 @@ def rn_codegen_modules( fbobjc_compiler_flags = get_apple_compiler_flags(), fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), ios_exported_headers = { - "{}.h".format(native_module_spec_name): ":{}".format(generate_module_hobjcpp_name), - "{}-generated.mm".format(native_module_spec_name): ":{}".format(generate_module_mm_name), + "{}/{}.h".format(native_module_spec_name, native_module_spec_name): ":{}".format(generate_module_hobjcpp_name), }, ios_headers = [ ":{}".format(generate_module_hobjcpp_name), From 521b16730dd07d80261086c2f33eed2a766d404e Mon Sep 17 00:00:00 2001 From: Tommy Nguyen Date: Tue, 29 Sep 2020 15:54:39 -0700 Subject: [PATCH 35/52] Align multi-line TextInput onSubmitEditing behavior (#29177) Summary: Aligns behavior to be consistent with Android and the [documentation](https://reactnative.dev/docs/textinput#bluronsubmit). `onSubmitEditing` should not be called when `blurOnSubmit=false`. ## Changelog [iOS] [Fixed] - Align multi-line TextInput onSubmitEditing behavior Pull Request resolved: https://github.com/facebook/react-native/pull/29177 Test Plan: ![textinput-blur-align](https://user-images.githubusercontent.com/4123478/85121116-85b4b200-b224-11ea-86c5-065e9e6d22ba.gif) Reviewed By: shergin Differential Revision: D22488870 Pulled By: hramos fbshipit-source-id: 2dec3a55da6384389a8358896ef1fbfd806d0304 --- Libraries/Text/TextInput/RCTBaseTextInputView.m | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 01ab7f19d12267..e8b87f333ddcec 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -365,11 +365,13 @@ - (BOOL)textInputShouldReturn // `onSubmitEditing` is called when "Submit" button // (the blue key on onscreen keyboard) did pressed // (no connection to any specific "submitting" process). - [_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit - reactTag:self.reactTag - text:[self.backedTextInputView.attributedText.string copy] - key:nil - eventCount:_nativeEventCount]; + if (_blurOnSubmit) { + [_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit + reactTag:self.reactTag + text:[self.backedTextInputView.attributedText.string copy] + key:nil + eventCount:_nativeEventCount]; + } return _blurOnSubmit; } From ca51dc6288eb8c8df197239cd53dff649da4e50d Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Tue, 29 Sep 2020 16:35:44 -0700 Subject: [PATCH 36/52] Fix mutation sorting function Summary: The sorting function currently forms a partial ordering, not a total ordering. This can cause problems with certain sequences of immediate or conflicting mutations, leading to UI corruption or crashes. Changelog: [Internal] Reviewed By: shergin Differential Revision: D24002668 fbshipit-source-id: edc9b4c1e3104897cb0c5fd6da563ec43d800494 --- .../LayoutAnimationKeyFrameManager.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h index e6aba6e3c07bcd..891d25d46d11ea 100644 --- a/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h +++ b/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h @@ -308,6 +308,14 @@ static inline bool shouldFirstComeBeforeSecondMutation( return true; } + // Update comes last, before deletes + if (rhs.type == ShadowViewMutation::Type::Update) { + return true; + } + if (lhs.type == ShadowViewMutation::Type::Update) { + return false; + } + // Remove comes before insert if (lhs.type == ShadowViewMutation::Type::Remove && rhs.type == ShadowViewMutation::Type::Insert) { @@ -317,6 +325,16 @@ static inline bool shouldFirstComeBeforeSecondMutation( lhs.type == ShadowViewMutation::Type::Insert) { return false; } + + // Create comes before insert + if (lhs.type == ShadowViewMutation::Type::Create && + rhs.type == ShadowViewMutation::Type::Insert) { + return true; + } + if (rhs.type == ShadowViewMutation::Type::Create && + lhs.type == ShadowViewMutation::Type::Insert) { + return false; + } } else { // Make sure that removes on the same level are sorted - highest indices // must come first. From b931bd33fee1a2a1fb4e26fcd5a469c16bfe425d Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 29 Sep 2020 18:38:24 -0700 Subject: [PATCH 37/52] TurboModule Android: properly set up RNTester ndkBuild and cleanup dependencies Summary: Before RNTester compilation starts, it needs to wait for :ReactAndroid NDK build to finish, so that it knows where to find the exported .so files. This tells the `preBuild` task to depends on `:ReactAndroid:prepareReactNdkLibs` task. The .so files are now copied over to the local project build dir, instead of depending on :ReactAndroid's build dir. For cleanup, the reverse ordering is needed: before `clean` removed our temp dir to store the copied .so files, make sure the ndkBuild cleanup tasks execute beforehand. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23982989 fbshipit-source-id: 955d7c9bccb5855b6b066fca89764df2ede89f63 --- ReactAndroid/Android-prebuilt.mk | 2 +- packages/rn-tester/android/app/build.gradle | 83 ++++++++++++++------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/ReactAndroid/Android-prebuilt.mk b/ReactAndroid/Android-prebuilt.mk index 4a4fb45ee1ff5b..394032a524ab95 100644 --- a/ReactAndroid/Android-prebuilt.mk +++ b/ReactAndroid/Android-prebuilt.mk @@ -24,7 +24,7 @@ REACT_ANDROID_SRC_DIR := $(REACT_ANDROID_DIR)/src/main REACT_COMMON_DIR := $(REACT_ANDROID_DIR)/../ReactCommon REACT_GENERATED_SRC_DIR := $(REACT_ANDROID_BUILD_DIR)/generated/source # Note: this only have .so, not .a -REACT_NDK_EXPORT_DIR := $(REACT_ANDROID_BUILD_DIR)/react-ndk/exported +REACT_NDK_EXPORT_DIR := $(PROJECT_BUILD_DIR)/react-ndk/exported # fb include $(CLEAR_VARS) diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index 2e70e9014a3d9b..fe95b03be0ccaf 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -186,33 +186,6 @@ android { } } -if (enableCodegen) { - def reactAndroidProjectDir = project(':ReactAndroid').projectDir; - android { - defaultConfig { - externalNativeBuild { - ndkBuild { - abiFilters "armeabi-v7a", "x86", "x86_64", "arm64-v8a" - arguments "APP_PLATFORM=android-16", - "APP_STL=c++_shared", - "NDK_TOOLCHAIN_VERSION=clang", - // The following paths assume building React Native from source. - "GENERATED_SRC_DIR=$buildDir/generated/source", - "REACT_ANDROID_DIR=$reactAndroidProjectDir" - cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" - cppFlags "-std=c++1y" - targets "rntester_appmodules" - } - } - } - externalNativeBuild { - ndkBuild { - path "$projectDir/src/main/jni/Android.mk" - } - } - } -} - configurations { hermesDebugImplementation {} hermesReleaseImplementation {} @@ -258,3 +231,59 @@ react { reactNativeRootDir = file("$rootDir") useJavaGenerator = System.getenv("USE_CODEGEN_JAVAPOET") ?: false } + +if (enableCodegen) { + // TODO: Move all this logic to CodegenPlugin.java. + def reactAndroidProjectDir = project(':ReactAndroid').projectDir; + def reactAndroidBuildDir = project(':ReactAndroid').buildDir; + + android { + defaultConfig { + externalNativeBuild { + ndkBuild { + abiFilters "armeabi-v7a", "x86", "x86_64", "arm64-v8a" + arguments "APP_PLATFORM=android-16", + "APP_STL=c++_shared", + "NDK_TOOLCHAIN_VERSION=clang", + // The following paths assume building React Native from source. + "GENERATED_SRC_DIR=$buildDir/generated/source", + "PROJECT_BUILD_DIR=$buildDir", + "REACT_ANDROID_DIR=$reactAndroidProjectDir" + cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" + cppFlags "-std=c++1y" + targets "rntester_appmodules" + } + } + } + externalNativeBuild { + ndkBuild { + path "$projectDir/src/main/jni/Android.mk" + } + } + } + + def packageReactNdkLibs = tasks.register("packageReactNdkLibs", Copy) { + // TODO: handle extracting .so from prebuilt :ReactAndroid. + dependsOn(":ReactAndroid:packageReactNdkLibs") + from("$reactAndroidBuildDir/react-ndk/exported") + into("$buildDir/react-ndk/exported") + } + + def cleanProjectNdkBuild = tasks.register("cleanProjectNdkBuild", Exec) { + ignoreExitValue(true) + tasks.forEach { + t -> + if (t.name.startsWith("externalNativeBuildClean")) { + dependsOn(t); + } + } + // This .cxx folder may cause stale ndkBuild configuration. + // See https://stackoverflow.com/a/58288851. + commandLine("rm", "-rf", "$projectDir/.cxx") + } + + afterEvaluate { + preBuild.dependsOn(packageReactNdkLibs) + clean.dependsOn(cleanProjectNdkBuild) + } +} From b9a1ea9e9e4586f3ae3e06709193c621c295ecd7 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 29 Sep 2020 18:38:24 -0700 Subject: [PATCH 38/52] TurboModule Android: move SampleTurboModule impl and spec to OSS Summary: This is the Java/JNI impl of the NativeSampleTurboModule.js, just like on iOS. The files here are supposed to be generated by the react-native-codegen, but they are checked in to the repo for easier build integration with RNTester. Changelog: [Internal] Reviewed By: hramos Differential Revision: D23985746 fbshipit-source-id: 46340d778f3d964efe5b538d15ebe0f2cab04862 --- ReactCommon/ReactCommon.podspec | 2 +- ReactCommon/react/nativemodule/samples/BUCK | 32 ++- .../NativeSampleTurboCxxModuleSpecJSI.cpp | 0 .../NativeSampleTurboCxxModuleSpecJSI.h | 0 .../SampleTurboCxxModule.cpp | 0 .../{ => ReactCommon}/SampleTurboCxxModule.h | 0 .../android/NativeSampleTurboModuleSpec.java | 91 ++++++++ .../ReactCommon/SampleTurboModuleSpec.cpp | 200 ++++++++++++++++++ .../ReactCommon/SampleTurboModuleSpec.h | 29 +++ .../platform/android/SampleTurboModule.java | 186 ++++++++++++++++ packages/rn-tester/Podfile.lock | 2 +- 11 files changed, 536 insertions(+), 6 deletions(-) rename ReactCommon/react/nativemodule/samples/{ => ReactCommon}/NativeSampleTurboCxxModuleSpecJSI.cpp (100%) rename ReactCommon/react/nativemodule/samples/{ => ReactCommon}/NativeSampleTurboCxxModuleSpecJSI.h (100%) rename ReactCommon/react/nativemodule/samples/{ => ReactCommon}/SampleTurboCxxModule.cpp (100%) rename ReactCommon/react/nativemodule/samples/{ => ReactCommon}/SampleTurboCxxModule.h (100%) create mode 100644 ReactCommon/react/nativemodule/samples/platform/android/NativeSampleTurboModuleSpec.java create mode 100644 ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp create mode 100644 ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h create mode 100644 ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java diff --git a/ReactCommon/ReactCommon.podspec b/ReactCommon/ReactCommon.podspec index 0c083cf2d5b133..c49fbd8c2c5459 100644 --- a/ReactCommon/ReactCommon.podspec +++ b/ReactCommon/ReactCommon.podspec @@ -54,7 +54,7 @@ Pod::Spec.new do |s| end ss.subspec "samples" do |sss| - sss.source_files = "react/nativemodule/samples/*.{cpp,h}", + sss.source_files = "react/nativemodule/samples/ReactCommon/**/*.{cpp,h}", "react/nativemodule/samples/platform/ios/**/*.{mm,cpp,h}" sss.dependency "ReactCommon/turbomodule/core", version end diff --git a/ReactCommon/react/nativemodule/samples/BUCK b/ReactCommon/react/nativemodule/samples/BUCK index c760c2f06218ab..b6b0fe3b974e52 100644 --- a/ReactCommon/react/nativemodule/samples/BUCK +++ b/ReactCommon/react/nativemodule/samples/BUCK @@ -1,13 +1,15 @@ load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "OBJC_ARC_PREPROCESSOR_FLAGS", "get_preprocessor_flags_for_build_mode", "get_static_library_ios_flags") -load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob") +load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "FBJNI_TARGET", "react_native_dep", "react_native_target", "react_native_xplat_target", "rn_android_library", "rn_xplat_cxx_library", "subdir_glob") rn_xplat_cxx_library( name = "samples", - srcs = glob(["*.cpp"]), + srcs = glob( + ["ReactCommon/**/*.cpp"], + ), header_namespace = "", exported_headers = subdir_glob( [ - ("", "*.h"), + ("ReactCommon", "*.h"), ], prefix = "ReactCommon", ), @@ -19,10 +21,11 @@ rn_xplat_cxx_library( ], fbandroid_deps = [ react_native_target("jni/react/jni:jni"), + FBJNI_TARGET, ], fbandroid_exported_headers = subdir_glob( [ - ("platform/android", "*.h"), + ("platform/android/ReactCommon", "*.h"), ], prefix = "ReactCommon", ), @@ -78,3 +81,24 @@ rn_xplat_cxx_library( react_native_xplat_target("react/nativemodule/core:core"), ], ) + +rn_android_library( + name = "impl", + srcs = glob(["platform/android/*.java"]), + required_for_source_only_abi = True, + visibility = [ + "PUBLIC", + ], + deps = [ + "//fbandroid/java/com/facebook/debug/log:log", + react_native_dep("third-party/java/jsr-305:jsr-305"), + react_native_dep("third-party/java/jsr-330:jsr-330"), + react_native_target("java/com/facebook/react/bridge:bridge"), + react_native_target("java/com/facebook/react/common:common"), + react_native_target("java/com/facebook/react/module/annotations:annotations"), + ":samples", + ], + exported_deps = [ + react_native_target("java/com/facebook/react/turbomodule/core/interfaces:interfaces"), + ], +) diff --git a/ReactCommon/react/nativemodule/samples/NativeSampleTurboCxxModuleSpecJSI.cpp b/ReactCommon/react/nativemodule/samples/ReactCommon/NativeSampleTurboCxxModuleSpecJSI.cpp similarity index 100% rename from ReactCommon/react/nativemodule/samples/NativeSampleTurboCxxModuleSpecJSI.cpp rename to ReactCommon/react/nativemodule/samples/ReactCommon/NativeSampleTurboCxxModuleSpecJSI.cpp diff --git a/ReactCommon/react/nativemodule/samples/NativeSampleTurboCxxModuleSpecJSI.h b/ReactCommon/react/nativemodule/samples/ReactCommon/NativeSampleTurboCxxModuleSpecJSI.h similarity index 100% rename from ReactCommon/react/nativemodule/samples/NativeSampleTurboCxxModuleSpecJSI.h rename to ReactCommon/react/nativemodule/samples/ReactCommon/NativeSampleTurboCxxModuleSpecJSI.h diff --git a/ReactCommon/react/nativemodule/samples/SampleTurboCxxModule.cpp b/ReactCommon/react/nativemodule/samples/ReactCommon/SampleTurboCxxModule.cpp similarity index 100% rename from ReactCommon/react/nativemodule/samples/SampleTurboCxxModule.cpp rename to ReactCommon/react/nativemodule/samples/ReactCommon/SampleTurboCxxModule.cpp diff --git a/ReactCommon/react/nativemodule/samples/SampleTurboCxxModule.h b/ReactCommon/react/nativemodule/samples/ReactCommon/SampleTurboCxxModule.h similarity index 100% rename from ReactCommon/react/nativemodule/samples/SampleTurboCxxModule.h rename to ReactCommon/react/nativemodule/samples/ReactCommon/SampleTurboCxxModule.h diff --git a/ReactCommon/react/nativemodule/samples/platform/android/NativeSampleTurboModuleSpec.java b/ReactCommon/react/nativemodule/samples/platform/android/NativeSampleTurboModuleSpec.java new file mode 100644 index 00000000000000..8475fbc4711299 --- /dev/null +++ b/ReactCommon/react/nativemodule/samples/platform/android/NativeSampleTurboModuleSpec.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// NOTE: This entire file should be codegen'ed. + +package com.facebook.fbreact.specs; + +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReactModuleWithSpec; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.common.build.ReactBuildConfig; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; + +public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaModule + implements ReactModuleWithSpec, TurboModule { + public NativeSampleTurboModuleSpec(ReactApplicationContext reactContext) { + super(reactContext); + } + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract double getNumber(double arg); + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract WritableMap getValue(double x, String y, ReadableMap z); + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract WritableMap getObject(ReadableMap arg); + + @ReactMethod + public abstract void voidFunc(); + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract WritableArray getArray(ReadableArray arg); + + @ReactMethod + public abstract void getValueWithPromise(boolean error, Promise promise); + + @ReactMethod + public abstract void getValueWithCallback(Callback callback); + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract String getString(String arg); + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract double getRootTag(double arg); + + @ReactMethod(isBlockingSynchronousMethod = true) + public abstract boolean getBool(boolean arg); + + protected abstract Map getTypedExportedConstants(); + + @Override + public final @Nullable Map getConstants() { + Map constants = getTypedExportedConstants(); + if (ReactBuildConfig.DEBUG || ReactBuildConfig.IS_INTERNAL_BUILD) { + Set obligatoryFlowConstants = + new HashSet<>(Arrays.asList("const2", "const1", "const3")); + Set optionalFlowConstants = new HashSet<>(); + Set undeclaredConstants = new HashSet<>(constants.keySet()); + undeclaredConstants.removeAll(obligatoryFlowConstants); + undeclaredConstants.removeAll(optionalFlowConstants); + if (!undeclaredConstants.isEmpty()) { + throw new IllegalStateException( + String.format("Native Module Flow doesn't declare constants: %s", undeclaredConstants)); + } + undeclaredConstants = obligatoryFlowConstants; + undeclaredConstants.removeAll(constants.keySet()); + if (!undeclaredConstants.isEmpty()) { + throw new IllegalStateException( + String.format("Native Module doesn't fill in constants: %s", undeclaredConstants)); + } + } + return constants; + } +} diff --git a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp new file mode 100644 index 00000000000000..b1c6922e3bb800 --- /dev/null +++ b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// NOTE: This entire file should be codegen'ed. + +#include + +namespace facebook { +namespace react { + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod(rt, VoidKind, "voidFunc", "()V", args, count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getBool( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod(rt, BooleanKind, "getBool", "(Z)Z", args, count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getNumber( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod(rt, NumberKind, "getNumber", "(D)D", args, count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getString( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, + StringKind, + "getString", + "(Ljava/lang/String;)Ljava/lang/String;", + args, + count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getArray( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, + ArrayKind, + "getArray", + "(Lcom/facebook/react/bridge/ReadableArray;)Lcom/facebook/react/bridge/WritableArray;", + args, + count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getObject( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, + ObjectKind, + "getObject", + "(Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/WritableMap;", + args, + count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod(rt, NumberKind, "getRootTag", "(D)D", args, count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getValue( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, + ObjectKind, + "getValue", + "(DLjava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/WritableMap;", + args, + count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, + VoidKind, + "getValueWithCallback", + "(Lcom/facebook/react/bridge/Callback;)V", + args, + count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, + PromiseKind, + "getValueWithPromise", + "(ZLcom/facebook/react/bridge/Promise;)V", + args, + count); +} + +static facebook::jsi::Value +__hostFunction_NativeSampleTurboModuleSpecJSI_getConstants( + facebook::jsi::Runtime &rt, + TurboModule &turboModule, + const facebook::jsi::Value *args, + size_t count) { + return static_cast(turboModule) + .invokeJavaMethod( + rt, ObjectKind, "getConstants", "()Ljava/util/Map;", args, count); +} + +NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI( + const JavaTurboModule::InitParams ¶ms) + : JavaTurboModule(params) { + methodMap_["voidFunc"] = + MethodMetadata{0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + methodMap_["getBool"] = + MethodMetadata{1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; + + methodMap_["getNumber"] = MethodMetadata{ + 1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; + + methodMap_["getString"] = MethodMetadata{ + 1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; + + methodMap_["getArray"] = + MethodMetadata{1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; + + methodMap_["getObject"] = MethodMetadata{ + 1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; + + methodMap_["getRootTag"] = MethodMetadata{ + 1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; + + methodMap_["getValue"] = + MethodMetadata{3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + + methodMap_["getValueWithCallback"] = MethodMetadata{ + 1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; + + methodMap_["getValueWithPromise"] = MethodMetadata{ + 1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + + methodMap_["getConstants"] = MethodMetadata{ + 0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h new file mode 100644 index 00000000000000..fd8f6c3c87eb10 --- /dev/null +++ b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// NOTE: This entire file should be codegen'ed. + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +/** + * C++ class for module 'SampleTurboModule' + */ + +class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public JavaTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java b/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java new file mode 100644 index 00000000000000..bc357d2baa3d9b --- /dev/null +++ b/ReactCommon/react/nativemodule/samples/platform/android/SampleTurboModule.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.fbreact.specs; + +import android.app.Activity; +import android.util.DisplayMetrics; +import android.widget.Toast; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeArray; +import com.facebook.react.bridge.WritableNativeMap; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.module.annotations.ReactModule; +import java.util.HashMap; +import java.util.Map; + +@ReactModule(name = SampleTurboModule.NAME) +public class SampleTurboModule extends NativeSampleTurboModuleSpec { + + public static final String NAME = "SampleTurboModule"; + + private static final String TAG = SampleTurboModule.class.getName(); + private final ReactApplicationContext mContext; + private Toast mToast; + + public SampleTurboModule(ReactApplicationContext context) { + super(context); + mContext = context; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public boolean getBool(boolean arg) { + log("getBool", arg, arg); + return arg; + } + + @Override + protected Map getTypedExportedConstants() { + Map result = new HashMap<>(); + DisplayMetrics displayMetrics = new DisplayMetrics(); + Activity activity = mContext.getCurrentActivity(); + if (activity != null) { + activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + result.put("const2", displayMetrics.widthPixels); + } + result.put("const1", true); + result.put("const3", "something"); + log("constantsToExport", "", result); + return result; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public double getNumber(double arg) { + log("getNumber", arg, arg); + return arg; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public String getString(String arg) { + log("getString", arg, arg); + return arg; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public double getRootTag(double arg) { + log("getRootTag", arg, arg); + return arg; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public void voidFunc() { + log("voidFunc", "", ""); + return; + } + + // This function returns {@link WritableMap} instead of {@link Map} for backward compat with + // existing native modules that use this Writable* as return types or in events. {@link + // WritableMap} is modified in the Java side, and read (or consumed) on the C++ side. + // In the future, all native modules should ideally return an immutable Map + @DoNotStrip + @Override + @SuppressWarnings("unused") + public WritableMap getObject(ReadableMap arg) { + WritableNativeMap map = new WritableNativeMap(); + map.merge(arg); + log("getObject", arg, map); + return map; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public WritableMap getValue(double numberArg, String stringArg, ReadableMap mapArg) { + WritableMap map = new WritableNativeMap(); + map.putDouble("x", numberArg); + map.putString("y", stringArg); + WritableMap zMap = new WritableNativeMap(); + zMap.merge(mapArg); + map.putMap("z", zMap); + log( + "getValue", + MapBuilder.of("1-numberArg", numberArg, "2-stringArg", stringArg, "3-mapArg", mapArg), + map); + return map; + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public void getValueWithCallback(final Callback callback) { + String result = "Value From Callback"; + log("Callback", "Return Time", result); + callback.invoke(result); + } + + @DoNotStrip + @SuppressWarnings("unused") + @Override + public WritableArray getArray(ReadableArray arg) { + if (arg == null || Arguments.toList(arg) == null) { + // Returning an empty array, since the super class always returns non-null + return new WritableNativeArray(); + } + WritableArray result = Arguments.makeNativeArray(Arguments.toList(arg)); + log("getArray", arg, result); + return result; + } + + @Override + @DoNotStrip + @SuppressWarnings("unused") + public void getValueWithPromise(boolean error, Promise promise) { + if (error) { + promise.reject( + "code 1", + "intentional promise rejection", + new Throwable("promise intentionally rejected")); + } else { + promise.resolve("result"); + } + } + + private void log(String method, Object input, Object output) { + if (mToast != null) { + mToast.cancel(); + } + StringBuilder message = new StringBuilder("Method :"); + message + .append(method) + .append("\nInputs: ") + .append(input.toString()) + .append("\nOutputs: ") + .append(output.toString()); + mToast = Toast.makeText(mContext, message.toString(), Toast.LENGTH_LONG); + mToast.show(); + } + + public void invalidate() {} + + @Override + public String getName() { + return NAME; + } +} diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index 0ea79d0fad55c3..1e99aa991cc571 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -524,7 +524,7 @@ SPEC CHECKSUMS: React-RCTText: 51a41bf9d18a91b2437b833ed4246754baf830d0 React-RCTVibration: a1cce36dd452eb88296d99d80d66f2c5bd50aad4 React-runtimeexecutor: 53867815d0a01e53a2c901cb7f01076216c5c799 - ReactCommon: dc40b68c9a72e99e07f831b0e87a859f4660208b + ReactCommon: d101410fc55088c91dc24595715c7b26ec760adf Yoga: 69ef0b2bba5387523f793957a9f80dbd61e89631 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a From 94b198cfd5d7d68a64bc8cb7b5a4df9f2be8b989 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 29 Sep 2020 18:38:24 -0700 Subject: [PATCH 39/52] TurboModule Android: install SampleTurboModule and the playground to RNTester Summary: This compiles SampleTurboModule into RNTester Android. It also adds the NativeModule playground to show case TurboModule system to RNTester examples, just like in iOS. {F337854369} Changelog: [Android][TurboModule] Added TurboModule example to RNTester when `USE_CODEGEN` is set Reviewed By: hramos Differential Revision: D24004711 fbshipit-source-id: b682dd51fa998ee2e60f8d6ffd8c39220d13a7fe --- .../samples/platform/android/Android.mk | 18 +++++ .../ReactCommon/SampleTurboModuleSpec.cpp | 9 +++ .../ReactCommon/SampleTurboModuleSpec.h | 5 +- packages/rn-tester/android/app/build.gradle | 8 ++ .../react/uiapp/RNTesterApplication.java | 78 +++++++++++++++---- .../android/app/src/main/jni/Android.mk | 4 + .../main/jni/RNTesterAppModuleProvider.cpp | 8 ++ .../js/utils/RNTesterList.android.js | 8 ++ 8 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 ReactCommon/react/nativemodule/samples/platform/android/Android.mk diff --git a/ReactCommon/react/nativemodule/samples/platform/android/Android.mk b/ReactCommon/react/nativemodule/samples/platform/android/Android.mk new file mode 100644 index 00000000000000..46dfd7623ae029 --- /dev/null +++ b/ReactCommon/react/nativemodule/samples/platform/android/Android.mk @@ -0,0 +1,18 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := sampleturbomodule +LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/ReactCommon/*.cpp) +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) +LOCAL_SHARED_LIBRARIES := libfbjni libreact_nativemodule_core +LOCAL_CFLAGS := \ + -DLOG_TAG=\"ReactNative\" +LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall + +include $(BUILD_STATIC_LIBRARY) diff --git a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp index b1c6922e3bb800..676a79ee5e76c0 100644 --- a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp +++ b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.cpp @@ -196,5 +196,14 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI( 0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; } +std::shared_ptr SampleTurboModuleSpec_ModuleProvider( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms) { + if (moduleName == "SampleTurboModule") { + return std::make_shared(params); + } + return nullptr; +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h index fd8f6c3c87eb10..6baefae6d890d9 100644 --- a/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h +++ b/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h @@ -19,11 +19,14 @@ namespace react { /** * C++ class for module 'SampleTurboModule' */ - class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public JavaTurboModule { public: NativeSampleTurboModuleSpecJSI(const JavaTurboModule::InitParams ¶ms); }; +std::shared_ptr SampleTurboModuleSpec_ModuleProvider( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms); + } // namespace react } // namespace facebook diff --git a/packages/rn-tester/android/app/build.gradle b/packages/rn-tester/android/app/build.gradle index fe95b03be0ccaf..186a325259e28d 100644 --- a/packages/rn-tester/android/app/build.gradle +++ b/packages/rn-tester/android/app/build.gradle @@ -184,6 +184,14 @@ android { proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" } } + sourceSets.main { + java { + // SampleTurboModule. + srcDirs += [ + "$rootDir/ReactCommon/react/nativemodule/samples/platform/android", + ] + } + } } configurations { diff --git a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java index c191ecaec94d9d..710d8e0c7254e5 100644 --- a/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java +++ b/packages/rn-tester/android/app/src/main/java/com/facebook/react/uiapp/RNTesterApplication.java @@ -10,16 +10,19 @@ import android.app.Application; import android.content.Context; import androidx.annotation.Nullable; +import com.facebook.fbreact.specs.SampleTurboModule; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; +import com.facebook.react.TurboReactPackage; import com.facebook.react.bridge.JSIModule; import com.facebook.react.bridge.JSIModulePackage; import com.facebook.react.bridge.JSIModuleProvider; import com.facebook.react.bridge.JSIModuleSpec; import com.facebook.react.bridge.JSIModuleType; import com.facebook.react.bridge.JavaScriptContextHolder; +import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.UIManager; import com.facebook.react.config.ReactFeatureFlags; @@ -27,6 +30,8 @@ import com.facebook.react.fabric.CoreComponentsRegistry; import com.facebook.react.fabric.FabricJSIModuleProvider; import com.facebook.react.fabric.ReactNativeConfig; +import com.facebook.react.module.model.ReactModuleInfo; +import com.facebook.react.module.model.ReactModuleInfoProvider; import com.facebook.react.shell.MainReactPackage; import com.facebook.react.turbomodule.core.TurboModuleManager; import com.facebook.react.views.text.ReactFontManager; @@ -34,7 +39,9 @@ import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class RNTesterApplication extends Application implements ReactApplication { @@ -57,7 +64,47 @@ public boolean getUseDeveloperSupport() { @Override public List getPackages() { - return Arrays.asList(new MainReactPackage()); + return Arrays.asList( + new MainReactPackage(), + new TurboReactPackage() { + public NativeModule getModule( + final String name, final ReactApplicationContext reactContext) { + if (!ReactFeatureFlags.useTurboModules) { + return null; + } + + if (SampleTurboModule.NAME.equals(name)) { + return new SampleTurboModule(reactContext); + } + + return null; + } + + // Note: Specialized annotation processor for @ReactModule isn't configured in OSS + // yet. For now, hardcode this information, though it's not necessary for most + // modules. + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return new ReactModuleInfoProvider() { + public Map getReactModuleInfos() { + final Map moduleInfos = new HashMap<>(); + if (ReactFeatureFlags.useTurboModules) { + moduleInfos.put( + SampleTurboModule.NAME, + new ReactModuleInfo( + SampleTurboModule.NAME, + "SampleTurboModule", + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + true // isTurboModule + )); + } + return moduleInfos; + } + }; + } + }); } @Nullable @@ -72,7 +119,7 @@ protected JSIModulePackage getJSIModulePackage() { public List getJSIModules( final ReactApplicationContext reactApplicationContext, final JavaScriptContextHolder jsContext) { - List specs = new ArrayList<>(); + final List specs = new ArrayList<>(); // Install the new native module system. if (ReactFeatureFlags.useTurboModules) { @@ -88,8 +135,9 @@ public JSIModuleProvider getJSIModuleProvider() { return new JSIModuleProvider() { @Override public JSIModule get() { - ReactInstanceManager reactInstanceManager = getReactInstanceManager(); - List packages = reactInstanceManager.getPackages(); + final ReactInstanceManager reactInstanceManager = + getReactInstanceManager(); + final List packages = reactInstanceManager.getPackages(); return new TurboModuleManager( jsContext, @@ -118,7 +166,7 @@ public JSIModuleType getJSIModuleType() { @Override public JSIModuleProvider getJSIModuleProvider() { - ComponentFactory ComponentFactory = new ComponentFactory(); + final ComponentFactory ComponentFactory = new ComponentFactory(); CoreComponentsRegistry.register(ComponentFactory); return new FabricJSIModuleProvider( reactApplicationContext, @@ -126,22 +174,22 @@ public JSIModuleProvider getJSIModuleProvider() { // TODO: T71362667 add ReactNativeConfig's support in RNTester new ReactNativeConfig() { @Override - public boolean getBool(String s) { + public boolean getBool(final String s) { return false; } @Override - public int getInt64(String s) { + public int getInt64(final String s) { return 0; } @Override - public String getString(String s) { + public String getString(final String s) { return ""; } @Override - public double getDouble(String s) { + public double getDouble(final String s) { return 0; } }); @@ -178,24 +226,24 @@ public ReactNativeHost getReactNativeHost() { * @param reactInstanceManager */ private static void initializeFlipper( - Context context, ReactInstanceManager reactInstanceManager) { + final Context context, final ReactInstanceManager reactInstanceManager) { if (BuildConfig.DEBUG) { try { /* We use reflection here to pick up the class that initializes Flipper, since Flipper library is not available in release mode */ - Class aClass = Class.forName("com.facebook.react.uiapp.ReactNativeFlipper"); + final Class aClass = Class.forName("com.facebook.react.uiapp.ReactNativeFlipper"); aClass .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .invoke(null, context, reactInstanceManager); - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { e.printStackTrace(); - } catch (NoSuchMethodException e) { + } catch (final NoSuchMethodException e) { e.printStackTrace(); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { e.printStackTrace(); - } catch (InvocationTargetException e) { + } catch (final InvocationTargetException e) { e.printStackTrace(); } } diff --git a/packages/rn-tester/android/app/src/main/jni/Android.mk b/packages/rn-tester/android/app/src/main/jni/Android.mk index 2029b87348dd24..6e003cdb953721 100644 --- a/packages/rn-tester/android/app/src/main/jni/Android.mk +++ b/packages/rn-tester/android/app/src/main/jni/Android.mk @@ -7,6 +7,9 @@ THIS_DIR := $(call my-dir) include $(REACT_ANDROID_DIR)/Android-prebuilt.mk +# SampleNativeModule +include $(REACT_COMMON_DIR)/react/nativemodule/samples/platform/android/Android.mk + LOCAL_PATH := $(THIS_DIR) include $(CLEAR_VARS) @@ -16,6 +19,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni LOCAL_SHARED_LIBRARIES := libfbjni libreact_nativemodule_core libturbomodulejsijni libreact_codegen_reactandroidspec +LOCAL_STATIC_LIBRARIES := libsampleturbomodule LOCAL_CFLAGS := \ -DLOG_TAG=\"ReactNative\" LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall diff --git a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp index 493d8267e3cf03..60d8c7fba84d60 100644 --- a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp +++ b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp @@ -9,6 +9,8 @@ #include #include +// TODO: Remove SampleTurboModule from ReactAndroidSpec, then uncomment. +// #include namespace facebook { namespace react { @@ -19,6 +21,12 @@ std::shared_ptr RNTesterAppModuleProvider(const std::string moduleN return module; } + // TODO: Remove SampleTurboModule from ReactAndroidSpec, then uncomment. + // module = SampleTurboModuleSpec_ModuleProvider(moduleName, params); + // if (module != nullptr) { + // return module; + // } + // TODO: fix up the ReactAndroidSpec_ModuleProvider() to avoid the Android prefix. if (moduleName == "DatePicker") { return std::make_shared(params); diff --git a/packages/rn-tester/js/utils/RNTesterList.android.js b/packages/rn-tester/js/utils/RNTesterList.android.js index bb509d0f3b0103..5971a0facf278c 100644 --- a/packages/rn-tester/js/utils/RNTesterList.android.js +++ b/packages/rn-tester/js/utils/RNTesterList.android.js @@ -264,6 +264,14 @@ const APIExamples: Array = [ }, ]; +if (global.__turboModuleProxy) { + APIExamples.push({ + key: 'TurboModuleExample', + category: 'Basic', + module: require('../examples/TurboModule/TurboModuleExample'), + }); +} + const Modules: any = {}; APIExamples.concat(ComponentExamples).forEach(Example => { From 1d89ef87b63e1eb2238a839ef2105a52ac1d2270 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Tue, 29 Sep 2020 18:38:24 -0700 Subject: [PATCH 40/52] TurboModule: exclude NativeSampleTurboModule in the schema Summary: The sample module is meant for demo only, but it lives alongside other core modules in react-native repo. For now, exclude it in the Flow-type parsing, just like `NativeUIManager.js` Changelog: [Internal] Reviewed By: hramos Differential Revision: D24005108 fbshipit-source-id: 9ef524bfe2778dd983c94d1701f9ce49da5e0a68 --- .../src/cli/combine/combine-js-to-schema-cli.js | 3 +++ .../app/src/main/jni/RNTesterAppModuleProvider.cpp | 12 +++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js b/packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js index f9a0a07d8c90af..30443a09c35381 100644 --- a/packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js +++ b/packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js @@ -32,6 +32,9 @@ fileList.forEach(file => { // NativeUIManager will be deprecated by Fabric UIManager. // For now, ignore this spec completely because the types are not fully supported. !f.endsWith('NativeUIManager.js') && + // NativeSampleTurboModule is for demo purpose. It should be added manually to the + // app for now. + !f.endsWith('NativeSampleTurboModule.js') && !f.includes('__tests'), ); allFiles.push(...dirFiles); diff --git a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp index 60d8c7fba84d60..06c20c981cd016 100644 --- a/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp +++ b/packages/rn-tester/android/app/src/main/jni/RNTesterAppModuleProvider.cpp @@ -9,8 +9,7 @@ #include #include -// TODO: Remove SampleTurboModule from ReactAndroidSpec, then uncomment. -// #include +#include namespace facebook { namespace react { @@ -21,11 +20,10 @@ std::shared_ptr RNTesterAppModuleProvider(const std::string moduleN return module; } - // TODO: Remove SampleTurboModule from ReactAndroidSpec, then uncomment. - // module = SampleTurboModuleSpec_ModuleProvider(moduleName, params); - // if (module != nullptr) { - // return module; - // } + module = SampleTurboModuleSpec_ModuleProvider(moduleName, params); + if (module != nullptr) { + return module; + } // TODO: fix up the ReactAndroidSpec_ModuleProvider() to avoid the Android prefix. if (moduleName == "DatePicker") { From 5bb54c90bddab6b1903ddf88777872fce0aa27a8 Mon Sep 17 00:00:00 2001 From: Joshua Selbo Date: Tue, 29 Sep 2020 18:39:15 -0700 Subject: [PATCH 41/52] Upgrade Robolectric from 4.3.1 -> 4.4 Summary: Changelog: [Internal] Reviewed By: jiawei-lyu Differential Revision: D23718455 fbshipit-source-id: 39c684722db1269e2179cf9680cb728be1171afb --- ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK | 2 +- tools/build_defs/oss/rn_defs.bzl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK b/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK index 2721f9cb923f4a..c774e197673e51 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK +++ b/ReactAndroid/src/test/java/com/facebook/react/bridge/BUCK @@ -15,7 +15,7 @@ rn_android_library( ], deps = [ react_native_android_toplevel_dep("third-party/java/mockito2:mockito2"), - react_native_dep("third-party/java/robolectric/4.3.1:robolectric"), + react_native_dep("third-party/java/robolectric/4.4:robolectric"), react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/uimanager:uimanager"), react_native_tests_target("java/org/mockito/configuration:configuration"), diff --git a/tools/build_defs/oss/rn_defs.bzl b/tools/build_defs/oss/rn_defs.bzl index 5553eb884af16d..8b83e282bef5e1 100644 --- a/tools/build_defs/oss/rn_defs.bzl +++ b/tools/build_defs/oss/rn_defs.bzl @@ -189,7 +189,7 @@ def rn_robolectric_test(name, srcs, vm_args = None, *args, **kwargs): kwargs["deps"] = kwargs.pop("deps", []) + [ react_native_android_toplevel_dep("third-party/java/mockito2:mockito2"), react_native_xplat_dep("libraries/fbcore/src/test/java/com/facebook/powermock:powermock2"), - react_native_dep("third-party/java/robolectric/4.3.1:robolectric"), + react_native_dep("third-party/java/robolectric/4.4:robolectric"), ] extra_vm_args = [ From c92e7674358da7089b1733c51faf5f2e02111d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 29 Sep 2020 21:46:05 -0700 Subject: [PATCH 42/52] TurboModule iOS: Remove module filters Summary: These native modules are now filtered downstream in `combine-js-to-schema-cli.js`. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24003572 fbshipit-source-id: d858dbf4a4b6d522ed528f9c2262f37243317160 --- scripts/generate-native-modules-specs.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/generate-native-modules-specs.sh b/scripts/generate-native-modules-specs.sh index c65f85aa8190c8..e72916bc138da1 100755 --- a/scripts/generate-native-modules-specs.sh +++ b/scripts/generate-native-modules-specs.sh @@ -42,13 +42,14 @@ step_build_codegen () { step_gen_schema () { describe "Generating schema from flow types" SRCS_DIR=$(cd "$RN_DIR/Libraries" && pwd) - grep --exclude NativeSampleTurboModule.js --exclude NativeUIManager.js --include=Native\*.js -rnwl "$SRCS_DIR" -e 'export interface Spec extends TurboModule' -e "export default \(TurboModuleRegistry.get(Enforcing)?\('.*\): Spec\);/" \ - | xargs "$YARN_BINARY" node "$CODEGEN_DIR/lib/cli/combine/combine-js-to-schema-cli.js" "$SCHEMA_FILE" + "$YARN_BINARY" node "$CODEGEN_DIR/lib/cli/combine/combine-js-to-schema-cli.js" "$SCHEMA_FILE" "$SRCS_DIR" } step_gen_specs () { describe "Generating native code from schema (iOS)" - "$YARN_BINARY" --silent node scripts/generate-native-modules-specs-cli.js ios "$SCHEMA_FILE" "$OUTPUT_DIR" + pushd "$RN_DIR" >/dev/null || exit + "$YARN_BINARY" --silent node scripts/generate-native-modules-specs-cli.js ios "$SCHEMA_FILE" "$OUTPUT_DIR" + popd >/dev/null || exit } step_build_codegen From d373a8d88c30af910133d97ae973d256c4479929 Mon Sep 17 00:00:00 2001 From: Joshua Selbo Date: Tue, 29 Sep 2020 22:49:21 -0700 Subject: [PATCH 43/52] Fix React Native Robolectric 4.4 deps (#30073) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/30073 Changelog: [Android][Added] - Test infra: Robolectric 4.3.1 -> 4.4 upgrade Reviewed By: fkgozali Differential Revision: D24009953 fbshipit-source-id: 70549187f4af0abd2ea10f6725eecadbaef7281b --- ReactAndroid/gradle.properties | 2 +- .../third-party/java/robolectric/4.4/BUCK | 216 ++++++++++++++++++ tools/build_defs/oss/rn_defs.bzl | 5 +- 3 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 ReactAndroid/src/main/third-party/java/robolectric/4.4/BUCK diff --git a/ReactAndroid/gradle.properties b/ReactAndroid/gradle.properties index 04ef27362cf6fc..766e22770f7b6c 100644 --- a/ReactAndroid/gradle.properties +++ b/ReactAndroid/gradle.properties @@ -7,7 +7,7 @@ POM_PACKAGING=aar MOCKITO_CORE_VERSION=2.26.0 POWERMOCK_VERSION=2.0.2 -ROBOLECTRIC_VERSION=4.3.1 +ROBOLECTRIC_VERSION=4.4 JUNIT_VERSION=4.12 FEST_ASSERT_CORE_VERSION=2.0M10 diff --git a/ReactAndroid/src/main/third-party/java/robolectric/4.4/BUCK b/ReactAndroid/src/main/third-party/java/robolectric/4.4/BUCK new file mode 100644 index 00000000000000..9033f5b0ce9705 --- /dev/null +++ b/ReactAndroid/src/main/third-party/java/robolectric/4.4/BUCK @@ -0,0 +1,216 @@ +load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") +load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library", "rn_prebuilt_jar") + +rn_android_library( + name = "robolectric", + visibility = ["PUBLIC"], + exported_deps = [ + ":android-all-4.1.2_r1-robolectric-r1", + ":bouncycastle", + ":guava", + ":javax-annotation-api", + ":javax-inject", + ":robolectric4-annotations-prebuilt", + ":robolectric4-junit-prebuilt", + ":robolectric4-pluginapi-prebuilt", + ":robolectric4-plugins-maven-dependency-resolver-prebuilt", + ":robolectric4-prebuilt", + ":robolectric4-resources-prebuilt", + ":robolectric4-sandbox-prebuilt", + ":robolectric4-shadowapi-prebuilt", + ":robolectric4-shadows-framework-prebuilt", + ":robolectric4-utils-prebuilt", + ":robolectric4-utils-reflector-prebuilt", + react_native_dep("third-party/java/asm:asm"), + react_native_dep("third-party/java/sqlite:sqlite"), + react_native_dep("third-party/java/junit:junit"), + react_native_dep("third-party/android/androidx:test-monitor"), + ], +) + +rn_prebuilt_jar( + name = "android-all-4.1.2_r1-robolectric-r1", # name defines filename used by robolectric in runtime + binary_jar = ":robolectric-android-all-binary.jar", + visibility = ["//ReactAndroid/..."], +) + +# This new rule will make the .jar file appear in the "right" location, +# though that may change in the future +fb_native.export_file( + name = "robolectric-android-all-binary.jar", + src = ":robolectric-android-all-binary-remote.jar", + out = "../android-all-4.1.2_r1-robolectric-r1.jar", # name defines filename used by robolectric in runtime +) + +fb_native.remote_file( + name = "robolectric-android-all-binary-remote.jar", + sha1 = "8355a2da59fe0233ca45070ca32f08da98d0b806", + url = "mvn:org.robolectric:android-all:jar:4.1.2_r1-robolectric-r1", +) + +rn_prebuilt_jar( + name = "bouncycastle", + binary_jar = ":bouncycastle-binary.jar", + visibility = ["//ReactAndroid/..."], +) + +fb_native.remote_file( + name = "bouncycastle-binary.jar", + sha1 = "320b989112f00a63a3bcfa5a98f31a4f865a20fa", + url = "mvn:org.bouncycastle:bcprov-jdk15on:jar:1.65", +) + +rn_prebuilt_jar( + name = "guava", + binary_jar = ":guava-binary.jar", + visibility = ["//ReactAndroid/..."], +) + +fb_native.remote_file( + name = "guava-binary.jar", + sha1 = "ef69663836b339db335fde0df06fb3cd84e3742b", + url = "mvn:com.google.guava:guava:jar:26.0-android", +) + +rn_prebuilt_jar( + name = "robolectric4-prebuilt", + binary_jar = ":robolectric4.jar", +) + +fb_native.remote_file( + name = "robolectric4.jar", + sha1 = "418c5bfae392fdbf71cd463a42a3e8c3b839a924", + url = "mvn:org.robolectric:robolectric:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-annotations-prebuilt", + binary_jar = ":robolectric4-annotations.jar", +) + +fb_native.remote_file( + name = "robolectric4-annotations.jar", + sha1 = "70fc5b1699467dfd7de606fc6c02ff9fc1816d9f", + url = "mvn:org.robolectric:annotations:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-junit-prebuilt", + binary_jar = ":robolectric4-junit.jar", +) + +fb_native.remote_file( + name = "robolectric4-junit.jar", + sha1 = "fbcda51d8e6f3a3897ae5cedc7aa481815745290", + url = "mvn:org.robolectric:junit:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-pluginapi-prebuilt", + binary_jar = ":robolectric4-pluginapi.jar", +) + +fb_native.remote_file( + name = "robolectric4-pluginapi.jar", + sha1 = "1ee94260f8c51620a35eac33fc1efc01350c751f", + url = "mvn:org.robolectric:pluginapi:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-plugins-maven-dependency-resolver-prebuilt", + binary_jar = ":robolectric4-plugins-maven-dependency-resolver.jar", +) + +fb_native.remote_file( + name = "robolectric4-plugins-maven-dependency-resolver.jar", + sha1 = "9241a3c4bd01627447c76d9b67614808c78ffdd9", + url = "mvn:org.robolectric:plugins-maven-dependency-resolver:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-resources-prebuilt", + binary_jar = ":robolectric4-resources.jar", +) + +fb_native.remote_file( + name = "robolectric4-resources.jar", + sha1 = "a2ee1324bcb62724e6cbfa655bdb5683948a554c", + url = "mvn:org.robolectric:resources:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-sandbox-prebuilt", + binary_jar = ":robolectric4-sandbox.jar", +) + +fb_native.remote_file( + name = "robolectric4-sandbox.jar", + sha1 = "03cedd73c5aedaf79fb9a593552816c9fb3282f2", + url = "mvn:org.robolectric:sandbox:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-shadowapi-prebuilt", + binary_jar = ":robolectric4-shadowapi.jar", +) + +fb_native.remote_file( + name = "robolectric4-shadowapi.jar", + sha1 = "529649474b53cf8f6f4a483044ade43aebed8a4c", + url = "mvn:org.robolectric:shadowapi:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-shadows-framework-prebuilt", + binary_jar = ":robolectric4-shadows-framework.jar", +) + +fb_native.remote_file( + name = "robolectric4-shadows-framework.jar", + sha1 = "90028766e71353ad6f57d7bcb56ac0d861da18c3", + url = "mvn:org.robolectric:shadows-framework:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-utils-prebuilt", + binary_jar = ":robolectric4-utils.jar", +) + +fb_native.remote_file( + name = "robolectric4-utils.jar", + sha1 = "c54b2638d64e7bd4e1e45c4fe8038305402bd711", + url = "mvn:org.robolectric:utils:jar:4.4", +) + +rn_prebuilt_jar( + name = "robolectric4-utils-reflector-prebuilt", + binary_jar = ":robolectric4-utils-reflector.jar", +) + +fb_native.remote_file( + name = "robolectric4-utils-reflector.jar", + sha1 = "44c40ac0d2ef1e7c8b0f6c4e224ef26d356170f1", + url = "mvn:org.robolectric:utils-reflector:jar:4.4", +) + +rn_prebuilt_jar( + name = "javax-annotation-api", + binary_jar = ":javax-annotation-api.jar", +) + +fb_native.remote_file( + name = "javax-annotation-api.jar", + sha1 = "934c04d3cfef185a8008e7bf34331b79730a9d43", + url = "mvn:javax.annotation:javax.annotation-api:jar:1.3.2", +) + +rn_prebuilt_jar( + name = "javax-inject", + binary_jar = ":javax-inject.jar", +) + +fb_native.remote_file( + name = "javax-inject.jar", + sha1 = "6975da39a7040257bd51d21a231b76c915872d38", + url = "mvn:javax.inject:javax.inject:jar:1", +) diff --git a/tools/build_defs/oss/rn_defs.bzl b/tools/build_defs/oss/rn_defs.bzl index 8b83e282bef5e1..7112b3a400e8ef 100644 --- a/tools/build_defs/oss/rn_defs.bzl +++ b/tools/build_defs/oss/rn_defs.bzl @@ -196,11 +196,12 @@ def rn_robolectric_test(name, srcs, vm_args = None, *args, **kwargs): "-XX:+UseConcMarkSweepGC", # required by -XX:+CMSClassUnloadingEnabled "-XX:+CMSClassUnloadingEnabled", "-XX:ReservedCodeCacheSize=150M", - "-Drobolectric.dependency.dir=buck-out/gen/ReactAndroid/src/main/third-party/java/robolectric/4.3.1", - "-Dlibraries=buck-out/gen/ReactAndroid/src/main/third-party/java/robolectric/4.3.1/*.jar", + "-Drobolectric.dependency.dir=buck-out/gen/ReactAndroid/src/main/third-party/java/robolectric/4.4", + "-Dlibraries=buck-out/gen/ReactAndroid/src/main/third-party/java/robolectric/4.4/*.jar", "-Drobolectric.logging.enabled=true", "-XX:MaxPermSize=620m", "-Drobolectric.offline=true", + "-Drobolectric.looperMode=LEGACY", ] if native.read_config("user", "use_dev_shm"): extra_vm_args.append("-Djava.io.tmpdir=/dev/shm") From 0544568d865c5a8885de1cef692adf6ad7fc285d Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Wed, 30 Sep 2020 08:33:28 -0700 Subject: [PATCH 44/52] Drop old state updates Summary: Changelog: [internal] Components can update state multiple times before the state update queue is flushed. This causes unnecessary layout/diff and mount passes. To solve this, drop stale state updates inside `stateUpdateQueue_ ` for specific `ShadowNodeFamily`. Delivering stale status updates is redundant. Let's take SafeAreaView as an example. It schedules 5-6 state updates before `stateUpdateQueue_` is flushed. That's unnecessary work blocking JS thread. We only care about the latest state update. Same for TextInput and other components using state updates. Reviewed By: JoshuaGross Differential Revision: D23987707 fbshipit-source-id: 2e3f92cc93af61d78ac564aa40aef165af64b8c1 --- ReactCommon/react/renderer/core/EventQueue.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ReactCommon/react/renderer/core/EventQueue.cpp b/ReactCommon/react/renderer/core/EventQueue.cpp index 2861d7a14f05ec..2db952292ff9ea 100644 --- a/ReactCommon/react/renderer/core/EventQueue.cpp +++ b/ReactCommon/react/renderer/core/EventQueue.cpp @@ -8,6 +8,7 @@ #include "EventQueue.h" #include "EventEmitter.h" +#include "ShadowNodeFamily.h" namespace facebook { namespace react { @@ -35,6 +36,12 @@ void EventQueue::enqueueEvent(const RawEvent &rawEvent) const { void EventQueue::enqueueStateUpdate(const StateUpdate &stateUpdate) const { { std::lock_guard lock(queueMutex_); + if (!stateUpdateQueue_.empty()) { + auto const position = stateUpdateQueue_.back(); + if (stateUpdate.family == position.family) { + stateUpdateQueue_.pop_back(); + } + } stateUpdateQueue_.push_back(stateUpdate); } From 8c77f7060c8337176e8e4b0a45cdf78361d278ee Mon Sep 17 00:00:00 2001 From: Riley Dulin Date: Wed, 30 Sep 2020 12:06:47 -0700 Subject: [PATCH 45/52] Remove idx package from inspector msggen Summary: This was causing a crash in babel: ``` $ babel src --out-dir bin --source-maps Error: Cannot find module 'babel-plugin-idx' from '~/fbsource/xplat/js/react-native-github/ReactCommon/hermes/inspector/tools/msggen' - If you want to resolve "idx", use "module:idx" { code: 'MODULE_NOT_FOUND' } ``` It didn't appear that this module was used, so I deleted it. Changelog: [Internal] Reviewed By: neildhar Differential Revision: D23993272 fbshipit-source-id: dd34f0fc652cb27c87c891ca37d0eba66a19a6cf --- ReactCommon/hermes/inspector/tools/msggen/.babelrc | 1 - ReactCommon/hermes/inspector/tools/msggen/package.json | 1 - ReactCommon/hermes/inspector/tools/msggen/yarn.lock | 5 ----- 3 files changed, 7 deletions(-) diff --git a/ReactCommon/hermes/inspector/tools/msggen/.babelrc b/ReactCommon/hermes/inspector/tools/msggen/.babelrc index b96eb4c692e218..8ad6d5109ddf39 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/.babelrc +++ b/ReactCommon/hermes/inspector/tools/msggen/.babelrc @@ -5,5 +5,4 @@ } }] ], - "plugins": ["idx"] } diff --git a/ReactCommon/hermes/inspector/tools/msggen/package.json b/ReactCommon/hermes/inspector/tools/msggen/package.json index 8ee113ea68d624..bcd465c61e42eb 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/package.json +++ b/ReactCommon/hermes/inspector/tools/msggen/package.json @@ -33,7 +33,6 @@ }, "dependencies": { "devtools-protocol": "0.0.730699", - "idx": "^2.1.0", "yargs": "^14.2.0" } } diff --git a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock index cf4d9eaa94aa58..47b1dacda9373d 100644 --- a/ReactCommon/hermes/inspector/tools/msggen/yarn.lock +++ b/ReactCommon/hermes/inspector/tools/msggen/yarn.lock @@ -2519,11 +2519,6 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -idx@^2.1.0: - version "2.5.6" - resolved "https://registry.yarnpkg.com/idx/-/idx-2.5.6.tgz#1f824595070100ae9ad585c86db08dc74f83a59d" - integrity sha512-WFXLF7JgPytbMgelpRY46nHz5tyDcedJ76pLV+RJWdb8h33bxFq4bdZau38DhNSzk5eVniBf1K3jwfK+Lb5nYA== - ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" From 7054e58de4857a1d2669e596b132256f1a1378a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Wed, 30 Sep 2020 13:24:57 -0700 Subject: [PATCH 46/52] iOS: fix ios-configure-glog.sh syntax issue Summary: A `cat` to file was removed accidentally, preventing the configuration script from executing successfully as part of a `pod install`. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D24024824 fbshipit-source-id: 94af0c6e663320bfac04ee8f6fb37bd4bdc379a4 --- scripts/ios-configure-glog.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ios-configure-glog.sh b/scripts/ios-configure-glog.sh index f527702bbd03c9..9642c5322d48b5 100755 --- a/scripts/ios-configure-glog.sh +++ b/scripts/ios-configure-glog.sh @@ -30,6 +30,7 @@ fi ./configure --host arm-apple-darwin +cat << EOF >> src/config.h /* Add in so we have Apple Target Conditionals */ #ifdef __APPLE__ #include From 8a31dfe567a22dbc018ea763b0a9706068276c4a Mon Sep 17 00:00:00 2001 From: simek Date: Wed, 30 Sep 2020 14:34:03 -0700 Subject: [PATCH 47/52] chore: update RNTester example link in PanResponder comment (#30051) Summary: This PR fixes a small leftover after the RNTester migration to the monorepo package - an invalid link in the `PanResponder` comment. Refs: * https://github.com/facebook/react-native/issues/29567 * facebook/react-native-website#2177 (the similar correction was a part of merged PR in the RN docs) ## Changelog [Internal][Fixed] PanResponder: correct example link in comment Pull Request resolved: https://github.com/facebook/react-native/pull/30051 Test Plan: N/A Reviewed By: fkgozali Differential Revision: D24025065 Pulled By: hramos fbshipit-source-id: 190486e458fb8e83a35fa2d3c62f4483f3a4334d --- Libraries/Interaction/PanResponder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Interaction/PanResponder.js b/Libraries/Interaction/PanResponder.js index 1aaf9fce9ecaee..4106597cb6d40c 100644 --- a/Libraries/Interaction/PanResponder.js +++ b/Libraries/Interaction/PanResponder.js @@ -121,7 +121,7 @@ const currentCentroidY = TouchHistoryMath.currentCentroidY; * ### Working Example * * To see it in action, try the - * [PanResponder example in RNTester](https://github.com/facebook/react-native/blob/master/RNTester/js/PanResponderExample.js) + * [PanResponder example in RNTester](https://github.com/facebook/react-native/blob/master/packages/rn-tester/js/examples/PanResponder/PanResponderExample.js) */ export type GestureState = {| From 18f7abae07b8ea60c7530a5d9f34541c50f5edd9 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Wed, 30 Sep 2020 17:05:05 -0700 Subject: [PATCH 48/52] Android: removed Robolectric 4.3.1 Buck configuration Summary: It was recently upgraded to 4.4, so we don't need the 4.3.1 anymore. Changelog: [Android][Removed] Removed Robolectric 4.3.1 setup Reviewed By: jselbo Differential Revision: D24030822 fbshipit-source-id: 09b3c577d32028723e7bbc02f13459a7ae69b749 --- .../third-party/java/robolectric/4.3.1/BUCK | 216 ------------------ 1 file changed, 216 deletions(-) delete mode 100644 ReactAndroid/src/main/third-party/java/robolectric/4.3.1/BUCK diff --git a/ReactAndroid/src/main/third-party/java/robolectric/4.3.1/BUCK b/ReactAndroid/src/main/third-party/java/robolectric/4.3.1/BUCK deleted file mode 100644 index aeca8ed4f5bd3a..00000000000000 --- a/ReactAndroid/src/main/third-party/java/robolectric/4.3.1/BUCK +++ /dev/null @@ -1,216 +0,0 @@ -load("//tools/build_defs:fb_native_wrapper.bzl", "fb_native") -load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_library", "rn_prebuilt_jar") - -rn_android_library( - name = "robolectric", - visibility = ["PUBLIC"], - exported_deps = [ - ":android-all-4.1.2_r1-robolectric-r1", - ":bouncycastle", - ":guava", - ":javax-annotation-api", - ":javax-inject", - ":robolectric4-annotations-prebuilt", - ":robolectric4-junit-prebuilt", - ":robolectric4-pluginapi-prebuilt", - ":robolectric4-plugins-maven-dependency-resolver-prebuilt", - ":robolectric4-prebuilt", - ":robolectric4-resources-prebuilt", - ":robolectric4-sandbox-prebuilt", - ":robolectric4-shadowapi-prebuilt", - ":robolectric4-shadows-framework-prebuilt", - ":robolectric4-utils-prebuilt", - ":robolectric4-utils-reflector-prebuilt", - react_native_dep("third-party/java/asm:asm"), - react_native_dep("third-party/java/sqlite:sqlite"), - react_native_dep("third-party/java/junit:junit"), - react_native_dep("third-party/android/androidx:test-monitor"), - ], -) - -rn_prebuilt_jar( - name = "android-all-4.1.2_r1-robolectric-r1", # name defines filename used by robolectric in runtime - binary_jar = ":robolectric-android-all-binary.jar", - visibility = ["//ReactAndroid/..."], -) - -# This new rule will make the .jar file appear in the "right" location, -# though that may change in the future -fb_native.export_file( - name = "robolectric-android-all-binary.jar", - src = ":robolectric-android-all-binary-remote.jar", - out = "../android-all-4.1.2_r1-robolectric-r1.jar", # name defines filename used by robolectric in runtime -) - -fb_native.remote_file( - name = "robolectric-android-all-binary-remote.jar", - sha1 = "8355a2da59fe0233ca45070ca32f08da98d0b806", - url = "mvn:org.robolectric:android-all:jar:4.1.2_r1-robolectric-r1", -) - -rn_prebuilt_jar( - name = "bouncycastle", - binary_jar = ":bouncycastle-binary.jar", - visibility = ["//ReactAndroid/..."], -) - -fb_native.remote_file( - name = "bouncycastle-binary.jar", - sha1 = "2507204241ab450456bdb8e8c0a8f986e418bd99", - url = "mvn:org.bouncycastle:bcprov-jdk15on:jar:1.59", -) - -rn_prebuilt_jar( - name = "guava", - binary_jar = ":guava-binary.jar", - visibility = ["//ReactAndroid/..."], -) - -fb_native.remote_file( - name = "guava-binary.jar", - sha1 = "ef69663836b339db335fde0df06fb3cd84e3742b", - url = "mvn:com.google.guava:guava:jar:26.0-android", -) - -rn_prebuilt_jar( - name = "robolectric4-prebuilt", - binary_jar = ":robolectric4.jar", -) - -fb_native.remote_file( - name = "robolectric4.jar", - sha1 = "66e4550b96285eadcb5a45a21ad6fbe8842fa960", - url = "mvn:org.robolectric:robolectric:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-annotations-prebuilt", - binary_jar = ":robolectric4-annotations.jar", -) - -fb_native.remote_file( - name = "robolectric4-annotations.jar", - sha1 = "3db63d633be908a18db18615b594f824c034ae6d", - url = "mvn:org.robolectric:annotations:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-junit-prebuilt", - binary_jar = ":robolectric4-junit.jar", -) - -fb_native.remote_file( - name = "robolectric4-junit.jar", - sha1 = "fcafc9942e8748c8bab832b022672ca21808c492", - url = "mvn:org.robolectric:junit:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-pluginapi-prebuilt", - binary_jar = ":robolectric4-pluginapi.jar", -) - -fb_native.remote_file( - name = "robolectric4-pluginapi.jar", - sha1 = "128acea3aed3bbe36f8fde865f3a26b920237718", - url = "mvn:org.robolectric:pluginapi:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-plugins-maven-dependency-resolver-prebuilt", - binary_jar = ":robolectric4-plugins-maven-dependency-resolver.jar", -) - -fb_native.remote_file( - name = "robolectric4-plugins-maven-dependency-resolver.jar", - sha1 = "b1ea126cb80dbba0c2947be9234bbe2877ce2a09", - url = "mvn:org.robolectric:plugins-maven-dependency-resolver:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-resources-prebuilt", - binary_jar = ":robolectric4-resources.jar", -) - -fb_native.remote_file( - name = "robolectric4-resources.jar", - sha1 = "e40030b0f6808ca378bd2c803713157ee4287ea0", - url = "mvn:org.robolectric:resources:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-sandbox-prebuilt", - binary_jar = ":robolectric4-sandbox.jar", -) - -fb_native.remote_file( - name = "robolectric4-sandbox.jar", - sha1 = "2302e406aebab5f6843dbf6c2f21952fa86ec26f", - url = "mvn:org.robolectric:sandbox:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-shadowapi-prebuilt", - binary_jar = ":robolectric4-shadowapi.jar", -) - -fb_native.remote_file( - name = "robolectric4-shadowapi.jar", - sha1 = "81dfcf4a45b623b7744e46358d01c7ce054d0fff", - url = "mvn:org.robolectric:shadowapi:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-shadows-framework-prebuilt", - binary_jar = ":robolectric4-shadows-framework.jar", -) - -fb_native.remote_file( - name = "robolectric4-shadows-framework.jar", - sha1 = "150103d5732c432906f6130b734e7452855dd67b", - url = "mvn:org.robolectric:shadows-framework:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-utils-prebuilt", - binary_jar = ":robolectric4-utils.jar", -) - -fb_native.remote_file( - name = "robolectric4-utils.jar", - sha1 = "97b0331b67d0e1dc8bf50e570b6feb017f62aed1", - url = "mvn:org.robolectric:utils:jar:4.3", -) - -rn_prebuilt_jar( - name = "robolectric4-utils-reflector-prebuilt", - binary_jar = ":robolectric4-utils-reflector.jar", -) - -fb_native.remote_file( - name = "robolectric4-utils-reflector.jar", - sha1 = "3428887d068b66e33026ac533ae4647355167658", - url = "mvn:org.robolectric:utils-reflector:jar:4.3", -) - -rn_prebuilt_jar( - name = "javax-annotation-api", - binary_jar = ":javax-annotation-api.jar", -) - -fb_native.remote_file( - name = "javax-annotation-api.jar", - sha1 = "934c04d3cfef185a8008e7bf34331b79730a9d43", - url = "mvn:javax.annotation:javax.annotation-api:jar:1.3.2", -) - -rn_prebuilt_jar( - name = "javax-inject", - binary_jar = ":javax-inject.jar", -) - -fb_native.remote_file( - name = "javax-inject.jar", - sha1 = "6975da39a7040257bd51d21a231b76c915872d38", - url = "mvn:javax.inject:javax.inject:jar:1", -) From c42183817dbac1fad9ded547cbcf0b91dfc08070 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Wed, 30 Sep 2020 19:21:57 -0700 Subject: [PATCH 49/52] Fixed incorrect assert in RCTScrollViewComponentView Summary: This diff removes an incorrect assert and replaces it with a debug-only verification phase that compares "what we want" with "what we get". Changelog: [Internal] Fabric-specific internal change. Reviewed By: PeteTheHeat Differential Revision: D23983123 fbshipit-source-id: 03a628b4f8baa1f5fe4b55354b7c943e38b5e537 --- .../ScrollView/RCTScrollViewComponentView.mm | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index 859b4582980e8a..848e26d2678584 100644 --- a/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -498,16 +498,15 @@ - (void)_remountChildren visibleFrame.size.width *= scale; visibleFrame.size.height *= scale; +#ifndef NDEBUG + NSMutableArray *> *expectedSubviews = [NSMutableArray new]; +#endif + NSInteger mountedIndex = 0; for (UIView *componentView in _childComponentViews) { BOOL shouldBeMounted = YES; BOOL isMounted = componentView.superview != nil; - // If a view is mounted, it must be mounted exactly at `mountedIndex` position. - RCTAssert( - !isMounted || [_containerView.subviews objectAtIndex:mountedIndex] == componentView, - @"Attempt to unmount improperly mounted component view."); - // It's simpler and faster to not mess with views that are not `RCTViewComponentView` subclasses. if ([componentView isKindOfClass:[RCTViewComponentView class]]) { RCTViewComponentView *viewComponentView = (RCTViewComponentView *)componentView; @@ -529,7 +528,24 @@ - (void)_remountChildren if (shouldBeMounted) { mountedIndex++; } + +#ifndef NDEBUG + if (shouldBeMounted) { + [expectedSubviews addObject:componentView]; + } +#endif + } + +#ifndef NDEBUG + RCTAssert( + _containerView.subviews.count == expectedSubviews.count, + @"-[RCTScrollViewComponentView _remountChildren]: Inconsistency detected."); + for (NSInteger i = 0; i < expectedSubviews.count; i++) { + RCTAssert( + [_containerView.subviews objectAtIndex:i] == [expectedSubviews objectAtIndex:i], + @"-[RCTScrollViewComponentView _remountChildren]: Inconsistency detected."); } +#endif } #pragma mark - RCTScrollableProtocol From 553fb8b28d0ad332d75a944d244832be3390b6ba Mon Sep 17 00:00:00 2001 From: Frieder Bluemle Date: Wed, 30 Sep 2020 22:14:21 -0700 Subject: [PATCH 50/52] Update Android Gradle plugin to 4.0.1 (#29013) Summary: This is a major version update that needs to be tested thoroughly. Android Studio 4.0.1 is now available in the stable channel https://androidstudio.googleblog.com/2020/05/android-studio-40-available-in-stable.html https://developer.android.com/studio/releases/gradle-plugin#4.0.1 ## Changelog [Android] [Changed] - Update Android Gradle plugin to 4.0.1 Pull Request resolved: https://github.com/facebook/react-native/pull/29013 Test Plan: Build project Closes https://github.com/facebook/react-native/issues/29044 Reviewed By: shergin Differential Revision: D24041233 Pulled By: fkgozali fbshipit-source-id: 68ef0f313aa773866e65796e323ed0f19f41f834 --- build.gradle.kts | 2 +- packages/react-native-codegen/android/build.gradle | 2 +- .../android/gradlePlugin-build/gradlePlugin/build.gradle | 2 +- template/android/build.gradle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 571f2db36b6c0f..a55cebbc57e9d2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ buildscript { jcenter() } dependencies { - classpath("com.android.tools.build:gradle:3.6.4") + classpath("com.android.tools.build:gradle:4.0.1") classpath("de.undercouch:gradle-download-task:4.0.2") // NOTE: Do not place your application dependencies here; they belong diff --git a/packages/react-native-codegen/android/build.gradle b/packages/react-native-codegen/android/build.gradle index 69934710e3bdca..e0cc63d645bbcf 100644 --- a/packages/react-native-codegen/android/build.gradle +++ b/packages/react-native-codegen/android/build.gradle @@ -12,7 +12,7 @@ buildscript { jcenter() } dependencies { - classpath("com.android.tools.build:gradle:3.6.4") + classpath("com.android.tools.build:gradle:4.0.1") } } diff --git a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/build.gradle b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/build.gradle index 616590c65c97b6..dd269383ec1416 100644 --- a/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/build.gradle +++ b/packages/react-native-codegen/android/gradlePlugin-build/gradlePlugin/build.gradle @@ -19,7 +19,7 @@ gradlePlugin { } dependencies { - implementation 'com.android.tools.build:gradle:3.6.4' + implementation 'com.android.tools.build:gradle:4.0.1' // Use the same Gson version that `com.android.tools.build:gradle` depends on. implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.google.guava:guava:29.0-jre' diff --git a/template/android/build.gradle b/template/android/build.gradle index 2bafa1f491c53c..2131e76d46d75d 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -13,7 +13,7 @@ buildscript { jcenter() } dependencies { - classpath("com.android.tools.build:gradle:3.6.4") + classpath("com.android.tools.build:gradle:4.0.1") // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From 8b7fd37b42469d5633fab943e5eba9b1611d1273 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Wed, 30 Sep 2020 22:38:12 -0700 Subject: [PATCH 51/52] Log View hierarchy if removeViewAt crashes Summary: If removeViewAt crashes, log the children of the parent view, and all of the parent's ancestors. Changelog: [Internal] Reviewed By: shergin Differential Revision: D24019515 fbshipit-source-id: c5b1ca0948ebc47f2648e161770affa8542ca5dd --- .../fabric/mounting/MountingManager.java | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java index 6ff40bda0ffb18..632f57af48fa38 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java @@ -63,9 +63,9 @@ public MountingManager(@NonNull ViewManagerRegistry viewManagerRegistry) { mViewManagerRegistry = viewManagerRegistry; } - private static void logViewHierarchy(ViewGroup parent) { + private static void logViewHierarchy(ViewGroup parent, boolean recurse) { int parentTag = parent.getId(); - FLog.e(TAG, " "); + FLog.e(TAG, " "); for (int i = 0; i < parent.getChildCount(); i++) { FLog.e( TAG, @@ -73,11 +73,24 @@ private static void logViewHierarchy(ViewGroup parent) { + i + " tag=" + parent.getChildAt(i).getId() - + " toString=" - + parent.getChildAt(i).toString() + + " class=" + + parent.getChildAt(i).getClass().toString() + ">"); } FLog.e(TAG, " "); + + if (recurse) { + FLog.e(TAG, "Displaying Ancestors:"); + ViewParent ancestor = parent.getParent(); + while (ancestor != null) { + ViewGroup ancestorViewGroup = (ancestor instanceof ViewGroup ? (ViewGroup) ancestor : null); + int ancestorId = ancestorViewGroup == null ? View.NO_ID : ancestorViewGroup.getId(); + FLog.e( + TAG, + ""); + ancestor = ancestor.getParent(); + } + } } /** @@ -218,7 +231,7 @@ public void addViewAt(final int parentTag, final int tag, final int index) { // Display children before inserting if (SHOW_CHANGED_VIEW_HIERARCHIES) { FLog.e(TAG, "addViewAt: [" + tag + "] -> [" + parentTag + "] idx: " + index + " BEFORE"); - logViewHierarchy(parentView); + logViewHierarchy(parentView, false); } try { @@ -243,7 +256,7 @@ public void addViewAt(final int parentTag, final int tag, final int index) { public void run() { FLog.e( TAG, "addViewAt: [" + tag + "] -> [" + parentTag + "] idx: " + index + " AFTER"); - logViewHierarchy(parentView); + logViewHierarchy(parentView, false); } }); } @@ -359,7 +372,7 @@ public void removeViewAt(final int tag, final int parentTag, final int index) { if (SHOW_CHANGED_VIEW_HIERARCHIES) { // Display children before deleting any FLog.e(TAG, "removeViewAt: [" + tag + "] -> [" + parentTag + "] idx: " + index + " BEFORE"); - logViewHierarchy(parentView); + logViewHierarchy(parentView, false); } ViewGroupManager viewGroupManager = getViewGroupManager(viewState); @@ -398,6 +411,7 @@ public void removeViewAt(final int tag, final int parentTag, final int index) { return; } + logViewHierarchy(parentView, true); throw new IllegalStateException( "Tried to remove view [" + tag @@ -431,6 +445,8 @@ public void removeViewAt(final int tag, final int parentTag, final int index) { // enough that we shouldn't try to change this invariant, without a lot of thought. int childCount = viewGroupManager.getChildCount(parentView); + logViewHierarchy(parentView, true); + throw new IllegalStateException( "Cannot remove child at index " + index @@ -451,7 +467,7 @@ public void run() { FLog.e( TAG, "removeViewAt: [" + tag + "] -> [" + parentTag + "] idx: " + index + " AFTER"); - logViewHierarchy(parentView); + logViewHierarchy(parentView, false); } }); } From dd35bf534c4ced6af853bf2c9a995808e42b8a95 Mon Sep 17 00:00:00 2001 From: Sam Goldman Date: Wed, 30 Sep 2020 23:31:51 -0700 Subject: [PATCH 52/52] Deploy Flow v0.135.0 Summary: Changelog: [Internal] Reviewed By: mroch Differential Revision: D24040584 fbshipit-source-id: 106caa00cadd6930685c0030ad74685c64572ba9 --- .flowconfig | 2 +- .flowconfig.android | 2 +- package.json | 2 +- repo-config/package.json | 2 +- template/_flowconfig | 2 +- yarn.lock | 8 ++++---- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.flowconfig b/.flowconfig index edd3fc461862b4..c8b28fb8c86800 100644 --- a/.flowconfig +++ b/.flowconfig @@ -75,4 +75,4 @@ untyped-import untyped-type-import [version] -^0.134.0 +^0.135.0 diff --git a/.flowconfig.android b/.flowconfig.android index 63d4ec5bcecaaa..8008aacbad5243 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -75,4 +75,4 @@ untyped-import untyped-type-import [version] -^0.134.0 +^0.135.0 diff --git a/package.json b/package.json index 433b4c90a32c7b..9dad79fee24983 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "ws": "^6.1.4" }, "devDependencies": { - "flow-bin": "^0.134.0", + "flow-bin": "^0.135.0", "react": "16.13.1" }, "detox": { diff --git a/repo-config/package.json b/repo-config/package.json index ea2ac36be0f543..3e7a2c74386a8e 100644 --- a/repo-config/package.json +++ b/repo-config/package.json @@ -33,7 +33,7 @@ "eslint-plugin-react-hooks": "^4.0.7", "eslint-plugin-react-native": "3.8.1", "eslint-plugin-relay": "1.7.1", - "flow-bin": "^0.134.0", + "flow-bin": "^0.135.0", "jest": "^26.0.1", "jest-junit": "^10.0.0", "jscodeshift": "^0.9.0", diff --git a/template/_flowconfig b/template/_flowconfig index b1e00ccf3aa23f..644e2a9d6cce2a 100644 --- a/template/_flowconfig +++ b/template/_flowconfig @@ -63,4 +63,4 @@ untyped-import untyped-type-import [version] -^0.134.0 +^0.135.0 diff --git a/yarn.lock b/yarn.lock index a043e328e032cd..08bfcfa0829276 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3102,10 +3102,10 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== -flow-bin@^0.134.0: - version "0.134.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.134.0.tgz#e98e5724f6ed5a1265cf904bbb5e4c096ea3a026" - integrity sha512-j5aCugO3jmwDsUKc+7KReArgnL6aVjHLo6DlozKhxKYN+TaP8BY+mintPSISjSQtKZFJyvoNAc1oXA79X5WjIA== +flow-bin@^0.135.0: + version "0.135.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.135.0.tgz#70bcd7bae0231777dd05cc8707ff34b37824bbad" + integrity sha512-E0JIKWopjULE/fl1X+j7rh0zgcgD5nubLs3HWYeYPo+nWFy8dALvrQbFcCFoPePrkhY/fffhN28t8P1zBxB2Yg== flow-parser@0.*, flow-parser@^0.121.0: version "0.121.0"