Граф коммитов

391 Коммитов

Автор SHA1 Сообщение Дата
Valentin Shergin 28c3981f73 Fabric: UIManagerBinding::setNativeProps
Summary: Pretty straightforward.

Reviewed By: sahrens

Differential Revision: D13114836

fbshipit-source-id: ff86b28d8764955383d4b46a369faf978825f6eb
2018-11-27 18:03:27 -08:00
Valentin Shergin 142dd7673e Fabric: UIManager::setNativeProps
Summary: Pretty straightforward wiring UIManager and the new feature in ShadowTree: we get the node, clone with the new props and then replace this.

Reviewed By: sahrens

Differential Revision: D13114788

fbshipit-source-id: 3a34fb879f3ec564c26278034a19b88518302de8
2018-11-27 18:03:27 -08:00
Valentin Shergin f42d2b9e32 Fabric: `ShadowTree::completeByReplacingShadowNode`
Summary: This method is the core of the future features: `setNativeProps` and `LocalState`.

Reviewed By: sahrens

Differential Revision: D13114789

fbshipit-source-id: 2138496c43c171fe27784b1959d86d6eec4638ee
2018-11-27 18:03:27 -08:00
Valentin Shergin d594d5a4e5 Fabric: `UIManagerBinding::getRelativeLayoutMetrics`
Summary: Exposing the getRelativeLayoutMetrics method to JS.

Reviewed By: mdvacca

Differential Revision: D13036552

fbshipit-source-id: de825dfde8e64163168510aea1eda77370753b29
2018-11-27 18:03:27 -08:00
Valentin Shergin e61a14e71d Fabric: RCTWeakEventEmitterWrapper, NSAttributedString and co.
Summary:
Previously, we stored a pointer to ShadowNode inside NSAttributedString's attributes to make possible retrieving an EventEmitter associated with some text fragment.
That worked fine besides only one caveat: the internal implementation of NSAttributedString is quite strange and that causes a memory leak. Because of some reason, NSAttributedString does not release stored attributes after own destruction (maybe OS uses some kind of caching).
So, now, instead of storing a strong pointer to ShadowNode inside NSAttributedString, we store a weak pointer to EventEmitter. Storing a weak pointer is okay because a desired lifetime of EventEmitter is guaranteed by LocalData stored inside a View. Storing a weak EventEmitter instead of weak ShadowNode will also help us with migration to ShadowView (we cannot store ShadowView weakly because it's a stack allocated object).

Reviewed By: sahrens

Differential Revision: D13196886

fbshipit-source-id: f8714e4b3709765629d6456edf0c635bf5f7c53b
2018-11-26 13:51:19 -08:00
Valentin Shergin 0ec1d21c2f Fabric: Fixed a retain cycle between ParagraphShadowNode, LocalData and AttributedString
Summary:
Consider this:
 * ParagraphShadowNode retains LocalData,
 * LocalData contains AttributedString,
 * AttributedString contains Fragments,
 * Fragment can contain a pointer to parent shadow node, so it can be the ParagraphShadowNode.

In this case it's a retain cycle.
We actually don't need to store pointers to not TextShadowNodes, so we don't now.

Later, after we fully migrate to ShadowView, we can remove this condition because it will become harmless.

Reviewed By: sahrens

Differential Revision: D13196885

fbshipit-source-id: d386ce0a067df0a72e6619d62d56038aaf80eccb
2018-11-26 13:51:19 -08:00
Valentin Shergin cd5f0bd95c Fabric: Stopping creating ShadowView instances for non-View ShadowNodes
Summary:
Apparently, the previous behavior brings more problems than some *possible-in-the-future* features and flexibility.
The new model allows us to easily implement "nested text" feature.

(We temporary hope the old behavious for Android only for compatibility reasons.)

Reviewed By: mdvacca

Differential Revision: D13176277

fbshipit-source-id: 01f7bfb3c2e70cc89d76ecb78add016ee91cbd63
2018-11-25 22:17:30 -08:00
David Vacca 89f647d521 Redefine hashcode for AttributedString
Summary:
This diff changes the method to calculate the hash of an AttributedString (removing shadowNode and parentShadowNode from it).
This is necessary becuase otherwise hashcode of clonned parent keep changing in every state change, when the text doesnt change

With this change we are able to cache spannables in android properly

Reviewed By: shergin

Differential Revision: D13189110

fbshipit-source-id: c1f7372809ce98a5b4d091485cc15281a4ab5e1e
2018-11-25 17:21:00 -08:00
David Vacca 3be2816aec Remove max and min font size from serialization of text attribute
Summary:
Removing two props that are not currently used

They are being set as quiet_NaN  in C++ and this brings problems in the Android side

Reviewed By: shergin

Differential Revision: D13188600

fbshipit-source-id: e8412497a80300cfbc3770b829e9633206aaf427
2018-11-25 17:21:00 -08:00
David Vacca eec9e4a2f9 Expose hash as part of text localdata
Summary: In this diff we expose the text local data hash to android, this will be used in the future to cache metadata when rendering text in android

Reviewed By: shergin

Differential Revision: D13161873

fbshipit-source-id: cd13a4beba75a3fe62ac9ff3def26f88e874834b
2018-11-25 17:20:59 -08:00
David Vacca 3b4d6d5ef5 Add systrace to calculation of Yoga layout() in Fabric
Summary: Simple diff that adds a systrace to start measuring the calculation of Yoga layout() in Fabric

Reviewed By: shergin

Differential Revision: D13124641

fbshipit-source-id: 6bd03e9f56524221f5d91606ffde50253673c1bb
2018-11-25 17:20:59 -08:00
David Vacca 10ce6c3e11 Refactor types used during yoga meassure calls
Summary: This diff refactors the types used when Yoga requires to measure the size of a View in C++

Reviewed By: shergin

Differential Revision: D13124086

fbshipit-source-id: 89dfe80bb41b4fb2eaba84af630d52ef2509b1e1
2018-11-25 17:20:59 -08:00
Valentin Shergin ecc7012179 Fabric: Fixed `AttributedString::operator==`
Summary: Trivial and shameful erratum.

Reviewed By: mdvacca

Differential Revision: D13166689

fbshipit-source-id: 75128299502bbc9ff5458c4381e7833aa451dd04
2018-11-22 00:54:03 -08:00
Valentin Shergin 9c961331dd Fabric: `ParagraphShadowNode::updateLocalDataIfNeeded()`
Summary: Now we don't update `LocalData` for `ParagraphShadowNode` if the attributed string hasn't changed.

Reviewed By: mdvacca

Differential Revision: D13160128

fbshipit-source-id: 6ffe76ad187452fa37ba36a132b885cbcedfd1d3
2018-11-21 17:16:49 -08:00
Valentin Shergin 7e57755cea Fabric: `UIManager::getRelativeLayoutMetrics`
Summary: This method is underlying infra for all `measure`-like methods exposed to JavaScript.

Reviewed By: mdvacca

Differential Revision: D13036553

fbshipit-source-id: cb5135f1db97ec8144b31a24ee4fb9f5d61f0df1
2018-11-21 17:16:48 -08:00
Valentin Shergin f8be867cd8 Fabric: Sharing a pointer to ShadowTreeRegister with UIManager
Summary: The diff adds a pointer to ShadowTreeRegistry to UIManager which enables the possibility of implementing ShadowTree mutating and inspecting methods like `setNativeProps` and `getRelativeLayoutMetrics`.

Reviewed By: mdvacca

Differential Revision: D13036549

fbshipit-source-id: 5ed1252d84c8dd895fe0e6e8cc71afbaa9dab4b7
2018-11-21 17:16:48 -08:00
Valentin Shergin b4fa1fa0c6 Fabric: Introducing ShadowTreeRegistry
Summary:
Why do we need a dedicated registry class?
* We need to simplify registry-related logic in Scheduler.
* We need to couple threading aspect of the registry with the registry itself, otherwise it's not clear why exactly we acquire the mutex. We also should not acquire the mutex in a per-method way (as we did before), because it's incorrect and misleading (only lines that access the registry should by protected).
* We need to have a way to share the registry with other classes (e.g. UIManager) without passing a reference to the whole Scheduler.

Reviewed By: mdvacca

Differential Revision: D13036550

fbshipit-source-id: 644da910e823666c586834a3da2b4cdcb90eebb2
2018-11-21 17:16:48 -08:00
Valentin Shergin 71208f05f4 Fabric: Getting rid of leftovers in Scheduler
Summary: Trivial. Those are not used.

Reviewed By: fkgozali

Differential Revision: D13017883

fbshipit-source-id: cf285e537eb85c8fca6852f7c03a5ef661b85757
2018-11-21 17:16:48 -08:00
Valentin Shergin 9eec2c33e6 Fabric: LayoutableShadowNode::getRelativeLayoutMetrics()
Summary:
The generic method that returns relative (to some specified node) layout metrics.
We need this as a building block to implement `UIManager.measure*()` methods family.

Reviewed By: mdvacca

Differential Revision: D12932549

fbshipit-source-id: 79064551d32b0cd40e72dc87d0ed194e3779ba29
2018-11-21 17:16:48 -08:00
Valentin Shergin 3ecf4eaccb Fabric: ShadowNode::backtrackAncestors(...)
Summary:
We have to have a way to backtrack a pointer to a parent node and this is generalized version of that.
This is the first naive implementations of the algorithm. We will invest in optimizing this later.

Reviewed By: mdvacca

Differential Revision: D12920856

fbshipit-source-id: 9facb4e16a0b5608feb6747df3804952025ef093
2018-11-21 17:16:48 -08:00
David Vacca 8367fa9644 Implement layout constraint when measuring text
Summary: This diff adds support for layout constraint when measuring text

Reviewed By: shergin

Differential Revision: D13111434

fbshipit-source-id: 0c8689e9ac8ce2281b03386f275d2a8e034f88d8
2018-11-17 02:27:20 -08:00
David Vacca 2dbe769c5a NIT remove unnecessary cast in measure
Summary: Trivial clean up of unnecessary cast in measure methods

Reviewed By: shergin

Differential Revision: D13108542

fbshipit-source-id: 93661f2f5322a790f2d578e6897b89cd1e205c3d
2018-11-17 02:27:20 -08:00
David Vacca dcf72ff88c Change font size default from 12 to 14
Summary: trivial change of the default font size from 12 to 14 to make it backward compatible with current version of RN

Reviewed By: shergin

Differential Revision: D13108543

fbshipit-source-id: e5e384c4459f2c87ee9589c4e00a0ab5d0c8a06a
2018-11-17 02:27:20 -08:00
David Vacca e02a24b738 Dispatch events asynchronously
Summary: This diff fixes the dispaching of Async Events in Android C++ layer to ensure proper asynchronouns dispatching in the JS thread.

Reviewed By: shergin

Differential Revision: D12988348

fbshipit-source-id: 7aa60b11e2c264c2e68354ed83eb75139060d211
2018-11-14 09:45:26 -08:00
empyrical 0436bfce3e UITemplateProcessor: Fix case of include path (#22239)
Summary:
This pull request fixes a path name to be a proper case in `UITemplateProcessor`, which fixes this build warning:

```
{snip}/react/uimanager/UITemplateProcessor.cpp:17:10: warning: non-portable path to file '<react/core/ComponentDescriptor.h>';
      specified path differs in case from file name on disk [-Wnonportable-include-path]
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         <react/core/ComponentDescriptor.h>
1 warning generated.
```
Pull Request resolved: https://github.com/facebook/react-native/pull/22239

Differential Revision: D13020871

Pulled By: shergin

fbshipit-source-id: 77555018cd569880518ff884ed8768effc4ea97e
2018-11-11 22:51:32 -08:00
David Vacca 33b966139e Avoid pre-allocating views for non-layoutable shadow nodes
Summary: This diff changes the behavior of the Scheduler.schedulerDidRequestPreliminaryViewAllocation to avoid pre-allocating views that are non-layoutables

Reviewed By: shergin

Differential Revision: D12962008

fbshipit-source-id: cb2670beafdcbd2116fbdaf2dc5d1b4726330ec2
2018-11-11 15:21:49 -08:00
Valentin Shergin 94d49e544d Fabric: Codemod: All `<fabric/...` includes were renamed to `<react/...`
Summary: We are moving to more stable APIs removing all mentiones of the effort name from the codebase.

Reviewed By: mdvacca

Differential Revision: D12912894

fbshipit-source-id: 4a0c6b9e7454b8b14e62d419e9e9311dc0c56e7a
2018-11-10 14:22:15 -08:00
Valentin Shergin d2408dd43a Fabric: Making EventEmitter::setEnabled additive
Summary: In the previous approach, when event emitter got disabled for split second, we could lose the EventTarget because JS GC can collect it before we re-enable this. Now we "over-enable" this first, and "under-disable" later.

Reviewed By: mdvacca

Differential Revision: D12990112

fbshipit-source-id: 4e3c0c0e05f03509ec72ca570f59ce16597353f0
2018-11-09 11:03:34 -08:00
David Vacca 28278e1b06 Fix Shimmer in Fabric Android
Summary: ShimmeringView is called: RTShimmeringView Android and ShimmeringView in iOS. This diff adds a mapping into ComponentDescriptorRegistry to temporary enable ShimmeringView component until we can unify names in JS.

Reviewed By: sahrens

Differential Revision: D12991351

fbshipit-source-id: 48e08b8021116221ccfd5f2512c76f65145baa2a
2018-11-09 10:38:50 -08:00
David Vacca 2b01da073c Expose rootTag / surfaceId as part of schedulerDidRequestPreliminaryViewAllocation method
Summary: This diff exposes rootTag as part of SchedulerDelegate.schedulerDidRequestPreliminaryViewAllocation(). This will be necessary to be able to pool views per Surface in Android

Reviewed By: shergin

Differential Revision: D12875656

fbshipit-source-id: d2a8c1f9bcc6b14c17b34bf59085da44ae3c3416
2018-11-08 16:57:46 -08:00
David Vacca 7b04f6aeaa Add systrace support in Fabric C++
Summary: This diff adds systrace support in the C++ side of Fabric

Reviewed By: ejanzer

Differential Revision: D12861373

fbshipit-source-id: 0291f3e406f239bbef3686ac0bba6e9f1c7eac57
2018-11-08 16:57:46 -08:00
David Vacca cd5009f713 Temporary disable AndroidSwipeRefreshLayout
Summary: AndroidSwipeRefreshLayout is rendered in the "Marketplace Your Items" screen altough it is disabled. This diff just temporary implements the AndroidSwipeRefreshLayout component as a View (similar to the iOS counterpart RefreshControl).

Reviewed By: shergin

Differential Revision: D10524049

fbshipit-source-id: 5df38fbdf1339b3857138d82a7100ec7f15854b3
2018-11-08 16:57:46 -08:00
Uladzislau Paulovich 50e9b0f297 Enable unused-private-field warning (#13450)
Summary:
Pull Request resolved: https://github.com/pytorch/pytorch/pull/13450

Pull Request resolved: https://github.com/facebook/react-native/pull/22065

This diff enables -Wunused-private-field clang warning for Android builds and fixes all broken targets.

Reviewed By: gkmhub

Differential Revision: D12881793

fbshipit-source-id: 515555661e137be9e7b20eac9b5bdcb549d6a094
2018-11-08 09:23:12 -08:00
empyrical 6b6a27c6b0 TouchEventEmitter: Fix assignment of Y coordinates (#22160)
Summary:
This patch fixes the the assignment of Y coordinate information in the event payloads in `TouchEventEmitter`, which were inadvertently being assigned X coordinate data.
Pull Request resolved: https://github.com/facebook/react-native/pull/22160

Differential Revision: D12943125

Pulled By: shergin

fbshipit-source-id: a3fde64c4d6c76784f1a0ac7cae4c0d62f3d4497
2018-11-06 11:13:40 -08:00
Valentin Shergin 786df48b50 Fabric: Making some picky compilers happy
Summary: Trivial nits.

Reviewed By: mdvacca

Differential Revision: D12897927

fbshipit-source-id: 61cec4a070218606d52f05740aacbfae1d2efd31
2018-11-06 11:03:51 -08:00
Valentin Shergin 18d8c48c01 Fabric: Introducing UIManagerBinding, a replacement for JSIFabricUIManager
Summary:
This diff changes how we expose UIManager to JavaScript realm and control ownership of it. This change should improve reliability and a thread-safety.

UIManagerBinding is a HostObject which consolidate ownership of UIManager. Now JavaScript's GC controls its lifetime which eliminates the possibility of calling some JS facing methods of UIManager using a dangling pointer.
Besides that, all API now imply that if the caller has a reference to jsi::Runtime, it calls the method on the proper thread (it's an implication of RuntimeExecutor design).

Reviewed By: sahrens

Differential Revision: D12876745

fbshipit-source-id: eb8c70317460df5b14e45031ad15fc6c8e5b5ce3
2018-11-06 11:03:51 -08:00
Valentin Shergin b9f9f3284e Fabric: A bunch of functions for converting JSI primitives to Fabric and vice-versa
Summary: We need to decouple this from actual JSI/UIManagerBinding implementation to make them more maintainable.

Reviewed By: sahrens

Differential Revision: D12876742

fbshipit-source-id: 30cad69d0a9761e2aa82f31d180e4b5a40cedb61
2018-11-06 11:03:51 -08:00
Valentin Shergin 6c5b8c603b Fabric: Introduced ComponentDescriptorRegistry::at() method family
Summary: This is more usable (because it allows to use `->` operator) and safe (const-style) methods replacing old `operator[]` methods.

Reviewed By: mdvacca

Differential Revision: D12876744

fbshipit-source-id: 8ea7398c9777f8be3e88db873ec00915d0761615
2018-11-06 11:03:50 -08:00
Valentin Shergin ee5061886e Fabric: Some helper classes and functions were moved to uimanager/primitives
Summary: Trivial.

Reviewed By: mdvacca

Differential Revision: D12876747

fbshipit-source-id: a2e72ecb69ffc3787f0d8b432f06b9c9715ac5b1
2018-11-06 11:03:50 -08:00
Valentin Shergin df4521e6c4 Fabric: Making jsi::Runtime a part of EventBeat and EventPipe
Summary:
We double down on JSI in Fabric. So, practically, JSI is now a hard dependency for Fabric. I hope it's for good.
Now `jsi::Runtime` is coupled with scheduling via `EventExecuter`, so we have to make `jsi::Runtime` a part of `EventBeat` to proxy runtime reference to bindgings.

Reviewed By: sahrens

Differential Revision: D12837225

fbshipit-source-id: 98edc33d6a3358e6c2905f2f03ce0004a9ca0503
2018-11-06 11:03:50 -08:00
Valentin Shergin 3110a67047 Fabric: Explicit clearing std::vector after moving from it
Summary: Apparently, the standard does not guarantee that the vector is empty after moving from it. So, let's clear it explicitly instead of asserting the emptiness.

Reviewed By: sahrens

Differential Revision: D12837227

fbshipit-source-id: 85dff6848707f4204f4c79be173064547e83c63e
2018-11-06 11:03:50 -08:00
Spencer Ahrens ac9e09d079 rename ReactBytecode -> UITemplate
Summary: React bytecode is kind of a different thing that sebmarkbage already has in mind so lets keep the namespace separate.

Reviewed By: mdvacca

Differential Revision: D12896293

fbshipit-source-id: e0f266da6e7a051bcf5defea49b958452342754d
2018-11-05 15:43:55 -08:00
Spencer Ahrens ccc8a425ad Cleanup a bunch of the JS stuff
Summary: Stricter flow typing, better naming, modularization with context objects, more extensible, etc.

Reviewed By: yungsters

Differential Revision: D10443440

fbshipit-source-id: 171358dfb105829b872d6379064ba4bc29ce34de
2018-11-05 15:43:55 -08:00
Spencer Ahrens 7b5277bb75 mostly working on Android + OTA
Summary:
It works great on iOS, and mostly works on Android, and is now OTA'able as part of the screen config! Haven't done template view yet. One remaining issue:

Layout is borked on Android. I'm guessing the issue has to do with the timing of setting the constraints in `updateRootLayoutSpecs` and calling `mBinding.startSurface` which actually builds the shadow tree. If I try to call `updateRootLayoutSpecs` earlier, it just crashes immediately. Here's the layout it spits out, which clearly has -440 for the x of 420006, which is the RCTText component, causing it to get cut off on the left of the screen:
```
updateLayoutMountItem for reactTag: 420006 x: -440, y: -13, width: 931, height: 78
updateLayoutMountItem for reactTag: 420010 x: 26, y: 79, width: 0, height: 1651
updateLayoutMountItem for reactTag: 420012 x: 0, y: 26, width: 0, height: 158
updateLayoutMountItem for reactTag: 420016 x: 0, y: 210, width: 454, height: 454
updateLayoutMountItem for reactTag: 420018 x: 454, y: 210, width: 455, height: 454
updateLayoutMountItem for reactTag: 420022 x: 0, y: 690, width: 454, height: 454
updateLayoutMountItem for reactTag: 420024 x: 454, y: 690, width: 455, height: 454
updateLayoutMountItem for reactTag: 420028 x: 0, y: 1171, width: 454, height: 454
updateLayoutMountItem for reactTag: 420030 x: 454, y: 1171, width: 455, height: 454
updateLayoutMountItem for reactTag: 420032 x: 0, y: 1651, width: 0, height: 0
```

Reviewed By: mdvacca

Differential Revision: D12813192

fbshipit-source-id: 450d646af4883ff25184141721351da67b091b7c
2018-11-05 15:43:55 -08:00
Spencer Ahrens aab01608ba Update and expand bytecode spec
Summary:
* Adds parent tag as param for createNode in place of explicit appendChild commands.
* Adds version info to bytecode
* Adds native conditional support:

Conditionals are represented in product code with the new `NativeConditional` React
component. It takes params necessary to construct a native function call, and takes
a render prop as a child that passes the value of the native call as an arg. In
prod, the component would actually call the native module and render with that value,
but in jest we render for *both* true and false and set them as children
of a new jest-only primitive/host component which we special-case and generate a
special command with `OP_CODE.conditional`, generate the appropriate bytecode commands
for each branch, and embed them as args in the conditional OP_CODE command. When
evaluating the bytecode, only one set of commands is executed, based on the native
module value (which is evaluated with another new opcode which computes the value
and stuffs it in a "register").

Obviously generating this bytecode is kind of a cludge compared to prepack, but
when I asked @[501709947:Dominic] about it, he said they had no bytecode spec right
now, so I'm running ahead with this prototype. The main thing I'm focused on is
the C++/RN bytecode interpretter - this jest stuff is just a way to generate bytecode
for it to consume which could be replaced or augmented with many other approaches,
such as prepack, server rendering, etc.

Also piggybacked a bunch of other cleanup.

Reviewed By: shergin

Differential Revision: D10277121

fbshipit-source-id: 15d3217a59ef481b574c742d17d8a7dc893cba90
2018-11-05 15:43:55 -08:00
Spencer Ahrens 10d41d4225 more lint auto fixing
Summary: ran `find js/react-native-github/ReactCommon | xargs arc lint -a`

Reviewed By: fkgozali

Differential Revision: D12902865

fbshipit-source-id: 9c68c0f7e28893e76df966ad4110299e89895454
2018-11-02 12:44:59 -07:00
Lucian Grijincu 2b603fd8eb BUCKFORMAT: apply on all of fbsource
Summary: $ hg files -X "fbandroid/experimental/*" -X "fbcode/experimental/*" -X "fbcode/compphoto/experimental/*" -X "fbobjc/Users/*" -X "xplat/experimental/*" -X fbandroid/apps/fblite/xMob-android/BUCK -I "**/{BUCK,TARGETS,*.bzl}" | xargs -P 50 -L 50 arc lint --apply-patches --take BUCKFORMAT

Reviewed By: zertosh

Differential Revision: D12888019

fbshipit-source-id: 970eaf3d87e6b211032e83004cbeeacfae873c25
2018-11-01 16:13:35 -07:00
Tim Yung a689711f68 RN: Missing Copyright Headers
Summary: Adds copyright headers to all files that are missing them.

Reviewed By: hramos

Differential Revision: D12837494

fbshipit-source-id: 6330a18919676dec9ff2c03b7c9329ed9127d930
2018-10-31 01:37:26 -07:00
Valentin Shergin 18423fe16b Fabric: Removing accidental unnecessary BUCK dep
Summary: Trivial.

Reviewed By: mdvacca

Differential Revision: D12840490

fbshipit-source-id: b97340e6369ecff7f22b0dc746d1596a86519eea
2018-10-30 14:39:33 -07:00
Valentin Shergin 8f04699c4c Fabric: New UIManager registration process (beginning)
Summary:
This diff introduces a new integration concept (called RuntimeExecutor) which consolidates `Runtime` and the dispatching mechanism.
As simple as that:
`using RuntimeExecutor = std::function<void(std::function<void(facebook::jsi::Runtime &runtime)> &&callback)>;`

Reviewed By: fkgozali

Differential Revision: D12816746

fbshipit-source-id: 9e27ef16b98af861d494fe50c7e50bd0536e6aaf
2018-10-29 13:06:24 -07:00