Summary: It's actually the first module in OSS which is typed with taking advantages of codegen.
Reviewed By: RSNara
Differential Revision: D16620334
fbshipit-source-id: 65d6656506f2a4c68d493939ecfa65ba975abead
Summary:
Original commit changeset: 420d29d262b6
Reverts https://github.com/facebook/react-native/pull/25793 / D16515465
Union type property is not supported by codegen. We don't want to support unions yet and because the improvement is not that big and not yet published as stable for OSS (neither used anywhere internally) we can safely revert it.
Reviewed By: RSNara
Differential Revision: D16621228
fbshipit-source-id: 2fa416eef1ae353990860026ca97d2b0b429a852
Summary:
## The Problem
1. `CatalystInstanceImpl` indirectly holds on to the `jsi::Runtime`. When you destroy `CatalystInstanceImpl`, you destroy the `jsi::Runtime`. As a part of reloading React Native, we destroy and re-create `CatalystInstanceImpl`, which destroys and re-creates the `jsi::Runtime`.
2. When JS passes in a callback to a TurboModule method, we take that callback (a `jsi::Function`) and wrap it in a Java `Callback` (implemented by `JCxxCallbackImpl`). This Java `Callback`, when executed, schedules the `jsi::Function` to be invoked on a Java thread at a later point in time. **Note:** The Java NativeModule can hold on to the Java `Callback` (and, by transitivity, the `jsi::Function`) for potentially forever.
3. It is a requirement of `jsi::Runtime` that all objects associated with the Runtime (ex: `jsi::Function`) must be destroyed before the Runtime itself is destroyed. See: https://fburl.com/m3mqk6wt
### jsi.h
```
/// .................................................... In addition, to
/// make shutdown safe, destruction of objects associated with the Runtime
/// must be destroyed before the Runtime is destroyed, or from the
/// destructor of a managed HostObject or HostFunction. Informally, this
/// means that the main source of unsafe behavior is to hold a jsi object
/// in a non-Runtime-managed object, and not clean it up before the Runtime
/// is shut down. If your lifecycle is such that avoiding this is hard,
/// you will probably need to do use your own locks.
class Runtime {
public:
virtual ~Runtime();
```
Therefore, when you delete `CatalystInstanceImpl`, you could end up with a situation where the `jsi::Runtime` is destroyed before all `jsi::Function`s are destroyed. In dev, this leads the program to crash when you reload the app after having used a TurboModule method that uses callbacks.
## The Solution
If the only reference to a `HostObject` or a `HostFunction` is in the JS Heap, then the `HostObject` and `HostFunction` destructors can destroy JSI objects. The TurboModule cache is the only thing, aside from the JS Heap, that holds a reference to all C++ TurboModules. But that cache (and the entire native side of `TurboModuleManager`) is destroyed when we call `mHybridData.resetNative()` in `TurboModuleManager.onCatalystInstanceDestroy()` in D16552730. (I verified this by commenting out `mHybridData.resetNative()` and placing a breakpoint in the destructor of `JavaTurboModule`). So, when we're cleaning up `TurboModuleManager`, the only reference to a Java TurboModule is the JS Heap. Therefore, it's safe and correct for us to destroy all `jsi::Function`s created by the Java TurboModule in `~JavaTurboModule`. So, in this diff, I keep a set of all `CallbackWrappers`, and explicitly call `destroy()` on them in the `JavaTurboModule` destructor. Note that since `~JavaTurboModule` accesses `callbackWrappers_`, it must be executed on the JS Thread, since `createJavaCallbackFromJSIFunction` also accesses `callbackWrappers_` on the JS Thread.
For additional safety, I also eagerly destroyed the `jsi::Function` after it's been invoked once. I'm not yet sure if we only want JS callbacks to only ever be invoked once. So, I've created a Task to document this work: T48128233.
Reviewed By: mdvacca
Differential Revision: D16623340
fbshipit-source-id: 3a4c3efc70b9b3c8d329f19fdf4b4423c489695b
Summary:
This uses a new helper called `dispatchCommand` that now exists on the renderer. This was added to the renderer here: https://github.com/facebook/react/pull/16085
In Paper it calls UIManager.dispatchViewManagerCommand and in Fabric it calls the c++ Fabric UIManager
Reviewed By: rickhanlonii
Differential Revision: D16578708
fbshipit-source-id: 30f9468a7fd48afb506c0ee49a460b949bc863a1
Summary:
`codegenNativeCommands` returns an object with functions for each command that has the previous behavior inside the React Renderer, and the new Fabric logic inside of the Fabric React Native Renderer.
Changelog:
[Internal] - Change AndroidDrawerLayoutNativeComponent to use JS codegen for commands
Reviewed By: rickhanlonii
Differential Revision: D16529887
fbshipit-source-id: 24a5307944a7f62e18482d60d26052fea3be2051
Summary: This diff implements the JSResponderHandler methods in the core of RN (scheduler API and friends)
Reviewed By: ejanzer
Differential Revision: D16543437
fbshipit-source-id: dac03e30c4330d182ecf134f3174ba942dbf7289
Summary:
This diff adds the new API required to implment JSResponderHandler in FabricUIManager
The new API differs from the old API, but since setJSResponder is called ONLY from JS it's not necessary to have this method as part of UIManager interface.
Reviewed By: JoshuaGross
Differential Revision: D16543440
fbshipit-source-id: ca4bd4c1e4df706cda0eb16798e01f3350558d06
Summary:
We found that many callsites existed that could be using the native driver, but weren't. In order to help people use it when appropriate and eventually switch the default, we are requiring that useNativeDriver is explicit, even when set to false.
For now, we are changing the flow type to turn this on at Facebook, but aren't making this a runtime warning until we have a bit more confidence in our plans so that we don't churn the community.
Reviewed By: mdvacca
Differential Revision: D16611301
fbshipit-source-id: dfa8536786fc949f0239118a9e0936b268b1081d
Summary: This gives a better error message when people use nullable refs for the flow type.
Reviewed By: mdvacca
Differential Revision: D16627409
fbshipit-source-id: 9ab1533b41a5a21e7557c0836feefff680e8018c
Summary: When you create a TurboModule from the JS side, we instantiate its Java class and simply make this `javaobject` a `jni::global_ref` in C++. But the reason why we need to make this a global ref is because `JavaTurboModule` needs it to be a global reference for method calls. Making this a `jni::global_ref` from the perspective to TurboModuleManager doesn't really make any sense. So, this diff refactors that bit of code.
Differential Revision: D16622133
fbshipit-source-id: 6a5c20bb405b945c06378a3423d5e7eb38ef244c
Summary:
## Description
When we reload the app, `ReactApplicationContext.destroy()` is called. This method calls `CatalystInstanceImpl.destroy()`, which (on the NativeModules thread) calls `NativeModuleRegistry.notifyJSInstanceDestroy()`, which loops over all its `ModuleHolder`s, and calls `ModuleHolder.destroy()`, each of which call their NativeModule's `onCatalystInstanceDestroy()` method.
TurboModuleManager is a `JSIModule`, so it also has its `onCatalystInstanceDestroy()` method called when the `ReactApplicationContext` is destroyed. But `TurboModuleManager.onCatalystInstanceDestroy()` doesn't do anything. Instead, at the very least, it should call `onCatalystInstanceDestroy()` of all NativeModules.
Differential Revision: D16622132
fbshipit-source-id: da29e698b5217232cfaa01e6f817aab18ceb526f
Summary: On iOS, calling the `__turboModuleProxy` function with the same name returns the same instance of the TurboModule. Adding this behaviour to Andorid as well.
Differential Revision: D16622131
fbshipit-source-id: 472011ac3356e7c30497f848be0c888596c449b1
Summary:
* Adds Flow types to `error-guard.js` and propagates them via the `ErrorUtils` module.
* Fixes some call sites to account for the stricter (correct) types.
Differential Revision: D16619538
fbshipit-source-id: c006ff2736ec380763956c4b89702cf44dd4deb0
Summary: Cpp and Objcpp should not be in the same rules since codegen has different purposes. I split them into into two rules and update tests for new names.
Reviewed By: TheSavior
Differential Revision: D16599257
fbshipit-source-id: 3a8be8c0e289825f9d5db831cc2eec3d2bf9728d
Summary: In this diff I add handling optional values in constants object. Behaviour is slightly different when it comes to string, objects etc., so I add tests for every of these cases.
Reviewed By: RSNara
Differential Revision: D16599254
fbshipit-source-id: 380c5235fefeb70a521733369011e0051e18859a
Summary: Same as title. Changing as per suggestion.
Reviewed By: furdei
Differential Revision: D16615807
fbshipit-source-id: 1c35ae1471beb2460e975841f367ffd49ce34494
Summary: Fabric ObjC(++) files will be prefixed by RN* for the time being, this codemod is a simple rename. This includes `interface` and `protocol` definition
Reviewed By: PeteTheHeat, yungsters
Differential Revision: D16611524
fbshipit-source-id: 868d2571ea2414dde4cbb3b75b1334b779b5d832
Summary: This diff registers the new Turbo Module SoundManager in Catalyst, FB4A and Workplace
Reviewed By: JoshuaGross
Differential Revision: D16543432
fbshipit-source-id: de3ab175befd5cc11403159e3aa42e5f17d0a280
Summary: This diff implements the Turbo Module SoundManager, this will be used by following diffs of the stack
Reviewed By: JoshuaGross
Differential Revision: D16543430
fbshipit-source-id: 34ba545f54b759fe4e49d4e3c5f8867205de907c
Summary: ComponentScript uses Dimensions, but doesn't support native modules, so we need to keep the `nativeExtensions` stuff that was dropped in D16525189.
Reviewed By: PeteTheHeat
Differential Revision: D16611233
fbshipit-source-id: c0add40529743e02ab7943814dc9f2188e8e0633
Summary:
In order to cleanup the callsites that are not using Animated's native driver, we are going to make useNativeDriver a required option so people have to think about whether they want the native driver or not.
I made this change by changing [Animated.js](https://fburl.com/ritcebri) to have this animation config type:
```
export type AnimationConfig = {
isInteraction?: boolean,
useNativeDriver: true,
onComplete?: ?EndCallback,
iterations?: number,
};
```
This causes Flow to error anywhere where useNativeDriver isn't set or where it is set to false.
I then used these Flow errors to codemod the callsites.
I got the location of the Flow errors by running:
```
flow status --strip-root --json --message-width=0 | jq '.errors | [.[].extra | .[].message | .[].loc | objects | {source: .source, start: .start, end: .end}]'
```
And then ran this codemod:
```
const json = JSON.parse('JSON RESULT FROM FLOW');
const fileLookup = new Map();
json.forEach(item => {
if (!fileLookup.has(item.source)) {
fileLookup.set(item.source, []);
}
fileLookup.get(item.source).push(item);
});
export default function transformer(file, api) {
const j = api.jscodeshift;
const filePath = file.path;
if (!fileLookup.has(filePath)) {
return;
}
const locationInfo = fileLookup.get(filePath);
return j(file.source)
.find(j.ObjectExpression)
.forEach(path => {
if (
path.node.properties.some(
property =>
property != null &&
property.key != null &&
property.key.name === 'useNativeDriver',
)
) {
return;
}
const hasErrorOnLine = locationInfo.some(
singleLocationInfo =>
singleLocationInfo.start.line === path.node.loc.start.line &&
Math.abs(
singleLocationInfo.start.column - path.node.loc.start.column,
) <= 2,
);
if (!hasErrorOnLine) {
return;
}
path.node.properties.push(
j.property(
'init',
j.identifier('useNativeDriver'),
j.booleanLiteral(false),
),
);
})
.toSource();
}
export const parser = 'flow';
```
```
yarn jscodeshift --parser=flow --transform addUseNativeDriver.js RKJSModules react-native-github
```
Followed up with
```
hg status -n --change . | xargs js1 prettier
```
Reviewed By: mdvacca
Differential Revision: D16611291
fbshipit-source-id: 1157587416ec7603d1a59e1fad6a821f1f57b952
Summary:
## The Problem
1. `CatalystInstanceImpl` indirectly holds on to the `jsi::Runtime`. When you destroy `CatalystInstanceImpl`, you destroy the `jsi::Runtime`. As a part of reloading React Native, we destroy and re-create `CatalystInstanceImpl`, which destroys and re-creates the `jsi::Runtime`.
2. When JS passes in a callback to a TurboModule method, we take that callback (a `jsi::Function`) and wrap it in a Java `Callback` (implemented by `JCxxCallbackImpl`). This Java `Callback`, when executed, schedules the `jsi::Function` to be invoked on a Java thread at a later point in time. **Note:** The Java NativeModule can hold on to the Java `Callback` (and, by transitivity, the `jsi::Function`) for potentially forever.
3. It is a requirement of `jsi::Runtime` that all objects associated with the Runtime (ex: `jsi::Function`) must be destroyed before the Runtime itself is destroyed. See: https://fburl.com/m3mqk6wt
### jsi.h
```
/// .................................................... In addition, to
/// make shutdown safe, destruction of objects associated with the Runtime
/// must be destroyed before the Runtime is destroyed, or from the
/// destructor of a managed HostObject or HostFunction. Informally, this
/// means that the main source of unsafe behavior is to hold a jsi object
/// in a non-Runtime-managed object, and not clean it up before the Runtime
/// is shut down. If your lifecycle is such that avoiding this is hard,
/// you will probably need to do use your own locks.
class Runtime {
public:
virtual ~Runtime();
```
Therefore, when you delete `CatalystInstanceImpl`, you could end up with a situation where the `jsi::Runtime` is destroyed before all `jsi::Function`s are destroyed. In dev, this leads the program to crash when you reload the app after having used a TurboModule method that uses callbacks.
## The Solution
If the only reference to a `HostObject` or a `HostFunction` is in the JS Heap, then the `HostObject` and `HostFunction` destructors can destroy JSI objects. The TurboModule cache is the only thing, aside from the JS Heap, that holds a reference to all C++ TurboModules. But that cache (and the entire native side of `TurboModuleManager`) is destroyed when we call `mHybridData.resetNative()` in `TurboModuleManager.onCatalystInstanceDestroy()` in D16552730. (I verified this by commenting out `mHybridData.resetNative()` and placing a breakpoint in the destructor of `JavaTurboModule`). So, when we're cleaning up `TurboModuleManager`, the only reference to a Java TurboModule is the JS Heap. Therefore, it's safe and correct for us to destroy all `jsi::Function`s created by the Java TurboModule in `~JavaTurboModule`. So, in this diff, I keep a set of all `CallbackWrappers`, and explicitly call `destroy()` on them in the `JavaTurboModule` destructor. Note that since `~JavaTurboModule` accesses `callbackWrappers_`, it must be executed on the JS Thread, since `createJavaCallbackFromJSIFunction` also accesses `callbackWrappers_` on the JS Thread.
For additional safety, I also eagerly destroyed the `jsi::Function` after it's been invoked once. I'm not yet sure if we only want JS callbacks to only ever be invoked once. So, I've created a Task to document this work: T48128233.
Reviewed By: mhorowitz
Differential Revision: D16589168
fbshipit-source-id: a1c0786999c22bef55d416beb0fc40261447a807
Summary: When you create a TurboModule from the JS side, we instantiate its Java class and simply make this `javaobject` a `jni::global_ref` in C++. But the reason why we need to make this a global ref is because `JavaTurboModule` needs it to be a global reference for method calls. Making this a `jni::global_ref` from the perspective to TurboModuleManager doesn't really make any sense. So, this diff refactors that bit of code.
Reviewed By: mdvacca
Differential Revision: D16555673
fbshipit-source-id: 2778fc5a372c41847e8296c2e22bb9a8826fcc52
Summary:
## Description
When we reload the app, `ReactApplicationContext.destroy()` is called. This method calls `CatalystInstanceImpl.destroy()`, which (on the NativeModules thread) calls `NativeModuleRegistry.notifyJSInstanceDestroy()`, which loops over all its `ModuleHolder`s, and calls `ModuleHolder.destroy()`, each of which call their NativeModule's `onCatalystInstanceDestroy()` method.
TurboModuleManager is a `JSIModule`, so it also has its `onCatalystInstanceDestroy()` method called when the `ReactApplicationContext` is destroyed. But `TurboModuleManager.onCatalystInstanceDestroy()` doesn't do anything. Instead, at the very least, it should call `onCatalystInstanceDestroy()` of all NativeModules.
Reviewed By: mdvacca
Differential Revision: D16552730
fbshipit-source-id: 04459185262e92d69570facb368578a848cc5fdb
Summary: On iOS, calling the `__turboModuleProxy` function with the same name returns the same instance of the TurboModule. Adding this behaviour to Andorid as well.
Reviewed By: mdvacca
Differential Revision: D16553363
fbshipit-source-id: c95e150d6967604a808cfb49877b7a633e33d729
Summary:
Previously codegenNativeCommands was just a hint to the babel transform. This meant that in order to use the codegen'd JS command functions it required having the babel transform turned on.
We aren't ready to turn the transform on for open source so we are adding runtime behavior to the function that will run when it isn't replaced with the transform.
Reviewed By: rickhanlonii
Differential Revision: D16574781
fbshipit-source-id: 583e8857f69ae1695445ee887432d15248dd35a9
Summary:
Original commit changeset: 34a8f8395ca7
The problem with the original commit was the usage of optional chaining. This diff removes the usage of optional chaining with good old fashioned null checks.
Reviewed By: rickhanlonii
Differential Revision: D16593623
fbshipit-source-id: d24cc40c85de9a2e712e5de19e9deb196003ccf2
Summary: This fixes the lint that was broken by D16543439
Reviewed By: fkgozali
Differential Revision: D16607092
fbshipit-source-id: 70c3989d25f446ffe0877e58253acef5ada8e010
Summary:
This diff contains bunch of minor and straightforward fixes which need to be shipped together. They are all related to integrating objCpp codegen and compiling examples.
#Facebook
I explain in comments my thoughts
Reviewed By: RSNara
Differential Revision: D16520560
fbshipit-source-id: 15392017a92f5a7ec5da71b552ec6c6904625a86
Summary:
View Pooling is not currently being used in Fabric Android, this diff removes all the extra abstractions that are being used becuase of the unused ViewPooling.
We might add this in the future when we re-implement view correctly.
Reviewed By: JoshuaGross
Differential Revision: D16543439
fbshipit-source-id: f41b6e02fddc36c7ef7a1052399d2e6b2041fcfb
Summary:
Duplicate category method implementations cause undefined behavior in Objective-C; one is chosen essentially at random. The linker also issues a noisy warning about this (which is how I noticed this case).
It didn't matter in this particular case since both implementations do the same thing, but we should clean this up so people don't get desensitized to these linker warnings. There is no need to have two implementations.
Reviewed By: fkgozali
Differential Revision: D16587219
fbshipit-source-id: 56dc3493735443c476484092f4a7eacfcddee8cb
Summary:
Added an array to maintain the counts of each of the reason of measure callbacks
and this is now added as qpl metadata in Layout Calculation qpl event
Reviewed By: davidaurelio
Differential Revision: D16516379
fbshipit-source-id: 201c5d2463f0a921841a0bbfec8f4d5e007000c8
Summary:
We had flex as a reason for both layout and measure. Now creating separating reason flexLayout and flexMeasure in this diff.
Also changed ordering of items in Enum to group layout and measure reasons
Reviewed By: davidaurelio
Differential Revision: D16562350
fbshipit-source-id: 75501f9d4dde0974009193b3991a8acc97b02ad0
Summary: In Dev Settings, we used to have an `Start Sampling Profiler on init` option, which was defunct. This diff re-enables that option. We can now start the Sampling Profiler on app start
Reviewed By: yinghuitan
Differential Revision: D7022382
fbshipit-source-id: 1db85d8a324e401c71187ba5871a91abcc18acf9
Summary: `parseErrorStack` (which uses the `stacktrace-parser` package) can return null file names, line numbers and column numbers. This diff updates the associated types and adds explicit null checks in some call sites.
Reviewed By: rickhanlonii
Differential Revision: D16542176
fbshipit-source-id: b72c73c05b95df0bbcb5b5baa7bc2d42cff1e074
Summary:
For other platforms such as React VR it doesn't make sense to use `IntentAndroid` native module and it should use `LinkingManager` instead.
The code used to be:
```
const LinkingManager =
Platform.OS === 'android'
? NativeModules.IntentAndroid
: NativeModules.LinkingManager;
```
This diff changes the behaviour back to what it used to be.
Reviewed By: cpojer
Differential Revision: D16561073
fbshipit-source-id: 544551f8ff1affca5a71835133e8a9e7abc75e1a
Summary: While adding support for this to React VR I noticed that `viewConfig.Manager` was `undefined` which meant that the view config never get assigned to the `viewManagerConfigs` object and caused errors later on. This change makes it so that even if `viewConfig.Manager` is not set the viewConfig still gets added to the `viewManagerConfigs` object.
Reviewed By: rickhanlonii
Differential Revision: D16560992
fbshipit-source-id: 626dc133602b142caff60f41d043d02968e6ccfc
Summary:
# Context
In https://github.com/facebook/react/pull/16141 we imported `ReactFiberErrorDialog` unchanged from React. That implementation was not idempotent: if passed the same error instance multiple times, it would amend its `message` property every time, eventually leading to bloat and low-signal logs.
The message bloat problem is most evident when rendering multiple `lazy()` components that expose the same Error reference to React (e.g. due to some cache that vends the same rejected Promise multiple times).
More broadly, there's a need for structured, machine-readable logging to replace stringly-typed interfaces in both the production and development use cases.
# This diff
* We leave the user-supplied `message` field intact and instead do all the formatting inside `ExceptionsManager`. To avoid needless complexity, this **doesn't** always have the exact same output as the old code (but it does come close). See tests for the specifics.
* The only mutation we do on React-captured error instances is setting the `componentStack` expando property. This replaces any previously-captured component stack rather than adding to it, and so doesn't create bloat.
* We also report the exception fields `componentStack`, unformatted `message` (as `originalMessage`) and `name` directly to `NativeExceptionsManager` for future use.
Reviewed By: cpojer
Differential Revision: D16331228
fbshipit-source-id: 7b0539c2c83c7dd4e56db8508afcf367931ac71d