Summary:
This diff adds support to Update Modal State when there is a change on the size of the screen
// TODO
Reviewed By: JoshuaGross
Differential Revision: D16000755
fbshipit-source-id: be87caa6d7f85c3d2778d2707c1e0cd821d6f6c6
Summary: This diff ensures only one thread access the Binding.schedulerDidFinishTransaction method
Reviewed By: shergin
Differential Revision: D15995971
fbshipit-source-id: 31f03803e8829480dd30b9b9148fd09b218ebeab
Summary: After we ran google-java-format D16071725, some Javadocs which weren't properly written broke. This includes putting unordered and ordered lists not using <ul> and <ol>, putting code blocks and pseudo-graphics not using <pre>. I ran through all the changed classes and tried to fix the broken Javadocs.
Reviewed By: cpojer
Differential Revision: D16090087
fbshipit-source-id: f31971cbc0e367a04814ff90bbfb2192751d5e16
Summary:
This diff formats the Java class files inside xplat/js/react-native-github. Since google-java-format was enabled in D16071401 we want to codemode the existing code so that users don't have to deal with formatter lint noise at diff-time.
```arc f --paths-cmd 'hg files -I "**/*.java"'```
drop-conflicts
Reviewed By: cpojer
Differential Revision: D16071725
fbshipit-source-id: fc6e3852e45742c109f0c5ac4065d64201c74204
Summary:
`WithDefault` appears not to be required to be prefixed with `?` because it's option value per se.
Fixed tests, removed `?` where needed, updated snapshots and review them. Added mechanism fro throwing error when `?WithDefault` found. Add tests for it.
Reviewed By: rubennorte
Differential Revision: D16048463
fbshipit-source-id: f55ed7454aacf0b8c42944a9b5c1037ad1b360fe
Summary: This is an attempt to use internal iOS plugin system for NativeModules in github.
Reviewed By: RSNara
Differential Revision: D16082484
fbshipit-source-id: 81d9f20b20419e9613a2babdd56d0e037705bf4e
Summary: First attempt to make RCTPlatform module implement the generated specs for TurboModule.
Reviewed By: PeteTheHeat
Differential Revision: D16001262
fbshipit-source-id: 24067c2840b9aa2be224c0c7c82fe7edc98d40d9
Summary: This defines various sub specs to support building TurboModules that implement the codegen'ed specs.
Reviewed By: PeteTheHeat
Differential Revision: D16043221
fbshipit-source-id: 27ed532be929c11c8fe648632da8a72061cbc8b0
Summary: Right now the entire RN core code lives inside one giant internal Buck target. This makes it hard to refactor the infra and to roll out TurboModules. For now, create a baseline for how RN core dir can be structured.
Reviewed By: PeteTheHeat
Differential Revision: D16001260
fbshipit-source-id: bba947e2fb75576a2e1f3f4c816575f1157dcb03
Summary:
NativeModuleRegistry is initialized in `ReactInstanceManager.createReactContext` and passed to the CatalystInstanceImpl's constructor. After we create the CatalystInstanceImpl, we then run the JS by calling `CatalystInstance.runJSBundle`. This makes it so that NativeModules are available by the time we run JS code that could require them.
With TurboModules, however, the JS startes executing first, and then we initialize TurboModuleManager. This is bad because by the time JS calls `TurboModuleRegistry.getEnforcing`, TurboModuleManager may yet not be ready. So, `TurboModuleRegistry.get` will just return null for all TurboModules. This will cause TurboModuleRegistry to raise errors. I suspect this is what's causing all RN surfaces to crash with "Unexpected error occurred" in prod builds of the app for users that are in the TurboModules FB4A test. But even if it doesn't fix the error, I think this is a better way to initialize TurboModules.
Reviewed By: ejanzer
Differential Revision: D16064364
fbshipit-source-id: 6053c251ace1668a331110d0cc64aba9d41a4837
Summary:
This PR adds support for custom `StickyHeaderComponent` to be used in ScrollView (and by extension in FlatList, SectionList..).
Motivation: I've been working on a FlatList with hidable header that has a search field in it. Something like https://medium.com/appandflow/react-native-collapsible-navbar-e51a049b560a but using a FlatList w/ pull-to-refresh. The implementation can be found at https://snack.expo.io/vonovak/hidable-header-flatlist .
I used the `ListHeaderComponent` prop to render the custom header - as opposed to absolute positioning which is used in the linked article because I also need the loading indicator (I added `refreshing` and `onRefresh` for that) to show up above the header.
I proceeded by adding `stickyHeaderIndices={[0]}` to keep the header at the top, which seems to be the idiomatic way to do so. Then I added `Animated.View` with custom translation logic to the rendered header.
All appears to be working fine at the first sight - when you tap any item, you'll see it react to touch (red underlay). You'll also see the header becomes hidden if I scroll far enough and appears again after scrolling up. BUT - when you scroll down so that the header becomes hidden and tap the first visible item in the list, it will not react to touches! The reason is that `ScrollViewStickyHeader`
https://github.com/facebook/react-native/blob/9a84970c35d22b68fb3d8eac019c7f415a14c888/Libraries/Components/ScrollView/ScrollView.js#L984
has its own translation logic and when I tap onto the item at the top of the list, it seems like I'm tapping the item but I'm in fact tapping that `ScrollViewStickyHeader`.
I tried working around this by not specifying `stickyHeaderIndices={[0]}` and using `ListHeaderComponentStyle` prop (this needed some additional changes in https://github.com/facebook/react-native/blob/9a84970c35d22b68fb3d8eac019c7f415a14c888/Libraries/Lists/VirtualizedList.js#L786, and the animation is junky for some reason - as if the header always needed to "catch up" with the scroll offset, causing jitter) and `CellRendererComponent` (junky animations too), but concluded that allowing to specify custom `StickyHeaderComponent` is the cleanest way to make something like this work. I'm slightly surprised I needed to do all this to make such a usual pattern work - am I missing something?
## Changelog
[GENERAL] [ADDED] - allow custom StickyHeader in ScrollView-based components
Pull Request resolved: https://github.com/facebook/react-native/pull/25428
Test Plan: This is a minor change that should not break anything; tested locally.
Differential Revision: D16073016
Pulled By: cpojer
fbshipit-source-id: cdb878d12a426068dbaa9a54367c1190a6c55328
Summary:
See https://fb.workplace.com/permalink.php?story_fbid=2337018256625463&id=100009037038038&substory_index=58 for motivation.
I opted for using a substring that is unlikely to come up in warnings in product code but is shared across all lean core warnings. I think this is good enough and won't require updates every time we deprecate a new module.
Reviewed By: yungsters
Differential Revision: D16073431
fbshipit-source-id: 136b9e8ab53c85d2de5ed7844780f5d082087a7d
Summary: This fixes an issue that caused us to show a confusing message on the initial load. I guess at some point the field was renamed. The code falls back to the "generic" message if it can't parse JSON, and in this case, it couldn't find the field called `description` as it's now called `message`.
Reviewed By: cpojer
Differential Revision: D16073931
fbshipit-source-id: a70ae28635b72f674cb1da26f89744b4214f18d9
Summary:
It's not needed to keep required providing default values even if they are not actually relevant.
Here I add a support for `null`, `0` of `false` instead by default and remove throwing errors if no other default value provided.
Reviewed By: rubennorte
Differential Revision: D16049047
fbshipit-source-id: bc4961af3873190568f2753fc4ec975354896df5
Summary:
It appears that `(e: BubblingEvent<T>) = mixed` exists only in given context and it's pointless to keep in this way. It could be simplified to `BubblingEventHandler<T>` without any negative consequences and that's the motivation of this diff.
The only tradeoff of this decision is leaving an opportunity to declare Bubbling/Direct event in the top of the file bc then analysing the code becomes much more difficult. However, it's not used anywhere so it's not a problem now and probably any time.
Also, changes the names to `DirectEventHandler` and `BubblingEventHandler` which are more related to current state. The names were updated in many places in code.
Reviewed By: rubennorte
Differential Revision: D16054571
fbshipit-source-id: 741d075eb46b80bac8eb73a6b30fc0b448cb3902
Summary:
This PR adjusts rncore generation to the flow parser based approach introduced in 98b03fa.
## Changelog
[Internal] [Fixed] - Fix iOS build of RNTester with fabric_enabled
Pull Request resolved: https://github.com/facebook/react-native/pull/25437
Test Plan:
As far as I see currently there's no automated testing for the RNTester build with `fabric_enbaled` set to `true`.
The quickest way to test this PR is building RNTester using cocoapods with `fabric_enabled`.
Differential Revision: D16071362
Pulled By: cpojer
fbshipit-source-id: 05d96686ea2d7c8c04f05eb7840c9eacff5a2738
Summary:
Looks we forgot to add this file to publish list. By adding it, we can remove some code in CLI that special-cases `react-native` package, since it now announces itself as a proper platform.
cc kelset, we'd like to have this cherry-picked for 0.60.
## Changelog
[Internal] [Fixed] - Publish `react-native.config.js`
Pull Request resolved: https://github.com/facebook/react-native/pull/25436
Test Plan: `npm pack` shows `react-native.config.js`
Differential Revision: D16071113
Pulled By: cpojer
fbshipit-source-id: df18affbb9a0ad7f2cfdd1a4cc93191aa5ffadeb
Summary:
Prior to this commit React Native on Android was not properly setting
the transform's scale properly correctly when setting it to 0. In order
to properly set one would need to use values close to 0, like 0.0001.
This was happing due to BaseViewManager sharing sMatrixDecompositionContext
across all views in a React Native app.
In some cases the decomposeMatrix() method from the MatrixMathHelper would
return early and not set any new values in sMatrixDecompositionContext
(this is, the new transform values) and
since this is a shared object the BaseViewManager would set the transform values
from the a previous transform.
In order to prevent this issue, before setting the new transform values
always reset the sMatrixDecompositionContext values.
## Changelog
[Android] [Fixed] - Reset sMatrixDecompositionContext before applying transformations
Pull Request resolved: https://github.com/facebook/react-native/pull/25438
Test Plan:
Run the code below on an Android device/emulator and you should see the following results:
### Android without the patch - current implementation
Notice that the scale 0 is not properly applied to the last rectangle and the second rectangle does not animate properly.

### Android with the patch
Everything works fine

### iOS - current implementation
Everything works fine

```javascript
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* format
* flow
*/
import React from 'react';
import { Animated, Button, StyleSheet, View, Text, SafeAreaView } from 'react-native';
const HorizontalContainer = ({ children, title }) => (
<View style={styles.horizontalContainer}>
{children}
<Text style={styles.text}>{title}</Text>
</View>
);
const App = () => {
const animValue1 = React.useRef(new Animated.Value(1)).current;
const animValue2 = React.useRef(new Animated.Value(1)).current;
const onStartAnim = React.useCallback(() => {
animValue1.setValue(0);
animValue2.setValue(0);
Animated.sequence([
Animated.timing(animValue1, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}),
Animated.timing(animValue2, {
toValue: 1,
delay: 700,
duration: 300,
useNativeDriver: true,
})
]).start();
}, [animValue1, animValue2]);
return (
<SafeAreaView style={styles.container}>
<Button title="Start Animation" onPress={onStartAnim} />
<HorizontalContainer title="Animated scale from 0 to 1">
<Animated.View style={[styles.view, { transform: [{ scaleX: animValue1 }] }]} />
</HorizontalContainer>
<HorizontalContainer title="Animated scale from 0 to 1 - delayed">
<Animated.View style={[styles.view, { transform: [{ scaleX: animValue2 }] }]} />
</HorizontalContainer>
<HorizontalContainer title="Scale 0.4">
<View style={[styles.view, { transform: [{ scaleX: 0.4 }] }]} />
</HorizontalContainer>
<HorizontalContainer title="Scale 0.2">
<View style={[styles.view, { transform: [{ scaleX: 0.2 }] }]} />
</HorizontalContainer>
<HorizontalContainer title="Scale 0">
<View style={[styles.view, { transform: [{ scaleX: 0 }, { translateY: 100 }] }]} />
</HorizontalContainer>
</SafeAreaView>
);
};
export default App;
const styles = StyleSheet.create({
text: {
fontSize: 10,
color: 'black',
marginLeft: 10,
},
horizontalContainer: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
flexDirection: 'row',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
view: {
width: 100,
height: 100,
backgroundColor: 'indigo',
marginVertical: 5,
}
});
```
Closes https://github.com/facebook/react-native/issues/25205
Closes https://github.com/facebook/react-native/issues/6278
Closes https://github.com/facebook/react-native/issues/6278
Differential Revision: D16071126
Pulled By: cpojer
fbshipit-source-id: 50820229db2e3c22cf6296831413d26b42f57070
Summary:
Previously, we stored `keyIndex_` in a Parser object which is incorrect because it makes the parsing process thread-unsafe (the Parser is shared between parsing processes).
That worked previously most of the time because we never parsed props concurrently but we actually do this in the native animation library.
Reviewed By: yungsters
Differential Revision: D16064557
fbshipit-source-id: 211f4301d0746e0f5126a1dcdd59f1ae9a420aa9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/25416
Use CocoaPods-based RNTesterPods workspace to run iOS unit tests and integration tests.
This is necessary as new iOS projects now use CocoaPods by default. CocoaPods also powers the new package auto-linking feature.
In order to provide test coverage for this new default configuration, our iOS tests are being migrated to use a CocoaPods-managed RNTester workspace. This applies to both Circle CI, and Sandcastle.
Changelog:
[iOS] [Changed] - Use RNTesterPods for iOS Tests
Reviewed By: fkgozali
Differential Revision: D16052466
fbshipit-source-id: 724b0c51008882d3c06a9074693fe23e74abe86b
Summary:
This breaks virtualization, viewability callbacks, and other features, so should be warned against.
Hopefully this would have made D15890785 trivial to figure out.
Reviewed By: PeteTheHeat
Differential Revision: D16040939
fbshipit-source-id: 593cd5da9891450fdcb501aef41455cf2d7baa4f
Summary: It just makes the code much more readable.
Reviewed By: sammy-SC
Differential Revision: D16038432
fbshipit-source-id: db68dd38356660078bc94ec802fbdbb6c27ceead
Summary:
Instead of checking whether `YG_ENABLE_EVENTS` is defined for every publish, we simply wrap the body of the `publish` function macro that delegates to the method that actually publishes the event.
This way we get
1. easier to write code where we publish events
2. more type safety when editing, enabling editors/IDEs to show errors without knowing about `YG_ENABLE_EVENTS`
Reviewed By: SidharthGuglani
Differential Revision: D16049888
fbshipit-source-id: cbf362d6f7be5053c3f377125d303b7137d6a241
Summary: Removes time measurements for measure callbacks. This functionality should not be part of Yoga/core, and can now be done by event subscribers themselves, as we have two events per measure callback.
Reviewed By: SidharthGuglani
Differential Revision: D16049812
fbshipit-source-id: e16556f3854e42f4bada39a97a668e718719b22c
Summary: Publishing two events will allow us to replace marker functionality completely with events. This also allows us to remove measuring time spent from Yoga itself.
Reviewed By: SidharthGuglani
Differential Revision: D16049810
fbshipit-source-id: 98628a92ed3c94d479e9fbcd53fac90c5f524087
Summary:
This diff adds a way for the codegen to handle view configs with non-standard top event names by adding a `paperTopLevelNameDeprecated` field to events in the schema.
## The problem
The problem this is solving is that Android host components build their own options for event settings in the view config. So instead of enforcing `onChange` to use the top level event name `topChange` like iOS does, Android can use `change` or `forbarChange` or anything the person adding the component wanted at the time:
```
// Expected
topChange: {
registrationName: 'onChange',
},
// Android
bringBackStargateYouCowards: {
registrationName: 'onChange',
},
```
This is possible because of the way Android builds these settings
```
// On iOS, notice that there's no option to change the top level name:
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTDirectEventBlock);
// On Android, you provide the top level event name
Override
public Map getExportedCustomDirectEventTypeConstants() {
return MapBuilder.of(
"bringBackStargateYouCowards",
MapBuilder.of("registrationName", "onChange"));
}
```
Since the codegen does not allow us to specify the top level event name (similar to iOS), we don't have a way to customize the names to support android
## The solution
To fix this, we're adding an extra option the event flow types:
```
onBubblingChange: (event: BubblingEvent<Event, 'customBubblingName'>) => void,
onDirectChange: (event: DirectEvent<Event, 'customDirectName'>) => void,
```
These will register **both** top level names in the view config:
```
{
directEventTypes: {
// Notice the same registration name is configured for different top level events
topChange: {
registrationName: 'onChange',
},
bringBackStargateYouCowards: {
registrationName: 'onChange',
},
}
}
```
This means when either `topChange` or `bringBackStargateYouCowards` fires it will call the onChange listener. **This gives us the flexibility to rename the native event name without breaking backwards compatibility.** Old apps will work when `bringBackStargateYouCowards` is fired, and new apps with an update will work when `topChange` fires.
Note: only the correct name will be generated for Fabric so technically we don't even really need to migrate the paper names and this prop can be deleted when paper is gone.
Reviewed By: cpojer
Differential Revision: D16042065
fbshipit-source-id: 40d076b43ffbbfc6c65c3c19de481d922a2add62
Summary:
Adding an instrumentation endpoint that allows us to write a snapshot out to an
arbitrary output stream. This is in addition to `createSnapshotFromFile`. I
reserve the right to replace the latter with the former in a later diff.
This is necessary to allow snapshots to be requested over the chrome debugger
protocol. The protocol sends the snapshot over the wire in chunks so we need
to be able to use an output stream that can do the chunking.
Because LLVM types are not available at the JSI layer, we accept a
`std::ostream` reference which we wrap with `llvm::raw_os_ostream` within
Hermes. We should not incur the static initializer cost (or other code bloat)
of using ostreams as a result.
Reviewed By: cwdick
Differential Revision: D16016319
fbshipit-source-id: 2d0b4848fd5cbe9ddee371d856cd8eb19dd80396
Summary:
@public
Removes the declaration of `YGRoundValueToPixelGrid` from `Yoga-internal.h`, as it is already declared in `Yoga.h`. `Yoga.h` is included from `Yoga-internal.h`
Reviewed By: SidharthGuglani
Differential Revision: D16047832
fbshipit-source-id: 72d9d2510372c983eedacc5d7af406b9346f18e6
Summary:
Depending on the style props of an Animated.View it may be optimised away
by the NativeViewHierarchyOptimizer, which will make the animation to
fail, because the native view is virtual (it does not exists
in the native view hierarchy).
Although the createAnimatedComponent already sets the collapsable property
based on the this._propsAnimated.__isNative flag, it won't work on all
cases, since the __isNative flag is only set when one starts the animation.
Which won't cause a re-render to occuor, thus not setting the collapsable
property to false.
In order to prevent this issue the HOC will just set the collapsable property
to false.
## Changelog
[Javascript] [Fixed] - Properly set collapsable to false before starting a nativeDriver animation
Pull Request resolved: https://github.com/facebook/react-native/pull/25361
Test Plan:
### **Without this patch:**
Run the following App on an Android device without this patch and click start.
Outcome: The animation **will not** make the text invisible.
### **With this patch:**
Run the following App on an Android device with this patch and click start.
Outcome: The animation **will** make the text invisible.
```javascript
import React, { Component, ReactNode } from 'react';
import { View, Text, TouchableOpacity, Animated, StyleSheet, Easing } from 'react-native';
interface Props { }
const Constants = {
animation: {
duration: 500,
},
};
const text =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed orci erat. Suspendisse feugiat elit gravida elit consequat ultrices. Sed sollicitudin ullamcorper molestie. Mauris a diam neque. Vivamus in lectus.';
class App extends Component<Props> {
anim: any;
constructor(props: Props) {
super(props);
this.anim = new Animated.Value(0);
}
handleStartPress = () => {
this.anim.setValue(0);
console.log('start');
Animated.timing(this.anim, {
duration: Constants.animation.duration,
toValue: 1,
easing: Easing.linear(),
useNativeDriver: true,
}).start();
};
render(): ReactNode {
return (
<View style={styles.container}>
<Animated.View
style={{
opacity: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}),
}}>
<Text>{text}</Text>
</Animated.View>
<TouchableOpacity
style={styles.startButton}
onPress={this.handleStartPress}>
<Text style={styles.startButtonText}>START</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: 'white',
flex: 1,
},
description: {
marginTop: 20,
paddingHorizontal: 10,
},
startButton: {
alignItems: 'center',
aspectRatio: 1,
backgroundColor: 'yellow',
borderRadius: 100,
height: 50,
justifyContent: 'center',
},
startButtonText: {
fontSize: 10,
fontWeight: 'bold',
},
});
export default App;
```
Closes https://github.com/facebook/react-native/issues/25318
Differential Revision: D15983822
Pulled By: cpojer
fbshipit-source-id: 1d790fbddc3103a2e34e114db956fa1fb465c1c9
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/25416
Use CocoaPods-based RNTesterPods workspace to run iOS unit tests and integration tests.
This is necessary as new iOS projects now use CocoaPods by default. CocoaPods also powers the new package auto-linking feature.
In order to provide test coverage for this new default configuration, our iOS tests are being migrated to use a CocoaPods-managed RNTester workspace. This applies to both Circle CI, and Sandcastle.
Reviewed By: fkgozali
Differential Revision: D15958209
fbshipit-source-id: b51fb907812cb2d4d78cce445d39bc253ae5acf8
Summary:
Apparently, settings `frame` and `transform` at the same view is UB and that's documented.
https://developer.apple.com/documentation/uikit/uiview/1622621-frame?language=objc
> Warning
> If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
Reviewed By: JoshuaGross
Differential Revision: D16038431
fbshipit-source-id: 9f282dfad97af293e5e70d3cdd849ae3e9c775c9
Summary: See the comment in the code.
Reviewed By: JoshuaGross
Differential Revision: D16031147
fbshipit-source-id: e165f423f5ee35d1ae5e667dba9ef8da7b9a388c
Summary:
This is a revamp of how we decide whether to stop at a refresh boundary or to bubble to the next one.
We used to decide that at module initialization. However, that's both unnecessary overhead on start (for modules you don't plan to edit), and is actually insufficient.
In particular, even if a module only exports components (and thus is a Refresh Boundary), consecutive versions of that module might not be compatible.
For example, any of these changes should trigger reevaluation of parents:
- Adding or removing exports
- Renaming the exported component (which probably means you exported a different one, and we shouldn't preserve state)
- Converting from a class to a function, or back
- Wrapping something in a HOC
The new system handles these cases by comparing the Refresh "families" corresponding to exports, and bubbling the update up if some of them don't match up.
The tests have been rewritten from the webpack-inspired `module.hot` API (which we no longer use directly) to the Refresh API.
Reviewed By: rubennorte
Differential Revision: D16036044
fbshipit-source-id: 18018548d4aaa05877ae6fbaffe40c993c77cdf0
Summary:
TurboModules seem to be pretty much done, but there's no easy way to reference them on iOS side if you're linking the React project (the classic, non-CocoaPods way). So I added it.
Also updated RNTester (non-CP based) to compile TM samples
## Changelog
[iOS] [Added] - RCTTurboModule now available from RCTTurboModules.xcodeproj
Pull Request resolved: https://github.com/facebook/react-native/pull/25031
Test Plan:
~~1. Add `#import <jsireact/TurboCxxModule.h>` to a `.h` file on iOS project -- see if it compiles correctly~~
1. Open RNTester/RNTester.xcodeproj, compile, and see if TurboModule sample works
Reviewed By: hramos
Differential Revision: D16019600
Pulled By: fkgozali
fbshipit-source-id: 53c691f035a4e02abd7569840137705f3862be81
Summary:
The function is not annotated with `const` so `plain()` will return a non-const
reference to the undecorated Runtime already. Seems like the const_cast was a
hold-over from a previous iteration.
Reviewed By: mhorowitz
Differential Revision: D16016320
fbshipit-source-id: 3dfa1e9acf2fc5c1ad61c9a8cd27c3c2e42036d3
Summary: These files are no longer needed since all files codegen'd use flow types as the source 🎉
Reviewed By: cpojer
Differential Revision: D15961378
fbshipit-source-id: 510a298b2e97cd78a9a3648cbaa239e8134daa75