Files
react-native/Libraries/Components/Touchable/PooledClass.js
T
Pieter Vanderwerff 66c6a75650 Suppress missing annotations in xplat/js
Summary: Add annotations to function parameters required for Flow's Local Type Inference project. This codemod prepares the codebase to match Flow's new typechecking algorithm. The new algorithm will make Flow more reliable and predictable.

Reviewed By: bradzacher

Differential Revision: D37388949

fbshipit-source-id: cdcbc98035ce9b6994842005ea46df42de54f9b8
2022-06-23 16:54:29 -07:00

124 lines
3.7 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
import invariant from 'invariant';
/**
* Static poolers. Several custom versions for each potential number of
* arguments. A completely generic pooler is easy to implement, but would
* require accessing the `arguments` object. In each of these, `this` refers to
* the Class itself, not an instance. If any others are needed, simply add them
* here, or in their own files.
*/
const oneArgumentPooler = function (copyFieldsFrom: any) {
const Klass = this; // eslint-disable-line consistent-this
if (Klass.instancePool.length) {
const instance = Klass.instancePool.pop();
Klass.call(instance, copyFieldsFrom);
return instance;
} else {
return new Klass(copyFieldsFrom);
}
};
const twoArgumentPooler = function (a1: any, a2: any) {
const Klass = this; // eslint-disable-line consistent-this
if (Klass.instancePool.length) {
const instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2);
return instance;
} else {
return new Klass(a1, a2);
}
};
const threeArgumentPooler = function (a1: any, a2: any, a3: any) {
const Klass = this; // eslint-disable-line consistent-this
if (Klass.instancePool.length) {
const instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3);
return instance;
} else {
return new Klass(a1, a2, a3);
}
};
const fourArgumentPooler = function (a1: any, a2: any, a3: any, a4: any) {
const Klass = this; // eslint-disable-line consistent-this
if (Klass.instancePool.length) {
const instance = Klass.instancePool.pop();
Klass.call(instance, a1, a2, a3, a4);
return instance;
} else {
return new Klass(a1, a2, a3, a4);
}
};
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
* LTI update could not be added via codemod */
const standardReleaser = function (instance) {
const Klass = this; // eslint-disable-line consistent-this
invariant(
instance instanceof Klass,
'Trying to release an instance into a pool of a different type.',
);
instance.destructor();
if (Klass.instancePool.length < Klass.poolSize) {
Klass.instancePool.push(instance);
}
};
const DEFAULT_POOL_SIZE = 10;
const DEFAULT_POOLER = oneArgumentPooler;
type Pooler = any;
/**
* Augments `CopyConstructor` to be a poolable class, augmenting only the class
* itself (statically) not adding any prototypical fields. Any CopyConstructor
* you give this may have a `poolSize` property, and will look for a
* prototypical `destructor` on instances.
*
* @param {Function} CopyConstructor Constructor that can be used to reset.
* @param {Function} pooler Customizable pooler.
*/
const addPoolingTo = function <T>(
CopyConstructor: Class<T>,
pooler: Pooler,
): Class<T> & {
getPooled(
...args: $ReadOnlyArray<mixed>
): /* arguments of the constructor */ T,
release(instance: mixed): void,
...
} {
// Casting as any so that flow ignores the actual implementation and trusts
// it to match the type we declared
const NewKlass = (CopyConstructor: any);
NewKlass.instancePool = [];
NewKlass.getPooled = pooler || DEFAULT_POOLER;
if (!NewKlass.poolSize) {
NewKlass.poolSize = DEFAULT_POOL_SIZE;
}
NewKlass.release = standardReleaser;
return NewKlass;
};
const PooledClass = {
addPoolingTo: addPoolingTo,
oneArgumentPooler: (oneArgumentPooler: Pooler),
twoArgumentPooler: (twoArgumentPooler: Pooler),
threeArgumentPooler: (threeArgumentPooler: Pooler),
fourArgumentPooler: (fourArgumentPooler: Pooler),
};
module.exports = PooledClass;