Avoid meta programming to initialize functions in module scope (#26388)

I'm trying to get rid of all meta programming in the module scope so
that closure can do a better job figuring out cyclic dependencies and
ability to reorder.

This is converting a lot of the patterns that assign functions
conditionally to using function declarations instead.

```
let fn;
if (__DEV__) {
  fn = function() {
    ...
  };
}
```
->
```
function fn() {
  if (__DEV__) {
    ...
  }
}
```
This commit is contained in:
Sebastian Markbåge 2023-03-14 21:00:22 -04:00 committed by GitHub
parent 21aee59e45
commit d310d654a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 611 additions and 635 deletions

View File

@ -13,7 +13,7 @@
* Change environment support for PointerEvent. * Change environment support for PointerEvent.
*/ */
const emptyFunction = function () {}; function emptyFunction() {}
export function hasPointerEvent() { export function hasPointerEvent() {
return global != null && global.PointerEvent != null; return global != null && global.PointerEvent != null;

View File

@ -94,15 +94,8 @@ const HTML = '__html';
let warnedUnknownTags: { let warnedUnknownTags: {
[key: string]: boolean, [key: string]: boolean,
}; };
let validatePropertiesInDevelopment;
let warnForPropDifference;
let warnForExtraAttributes;
let warnForInvalidEventListener;
let canDiffStyleForHydrationWarning; let canDiffStyleForHydrationWarning;
let normalizeHTML;
if (__DEV__) { if (__DEV__) {
warnedUnknownTags = { warnedUnknownTags = {
// There are working polyfills for <dialog>. Let people use it. // There are working polyfills for <dialog>. Let people use it.
@ -115,15 +108,6 @@ if (__DEV__) {
webview: true, webview: true,
}; };
validatePropertiesInDevelopment = function (type: string, props: any) {
validateARIAProperties(type, props);
validateInputProperties(type, props);
validateUnknownProperties(type, props, {
registrationNameDependencies,
possibleRegistrationNames,
});
};
// IE 11 parses & normalizes the style attribute as opposed to other // IE 11 parses & normalizes the style attribute as opposed to other
// browsers. It adds spaces and sorts the properties in some // browsers. It adds spaces and sorts the properties in some
// non-alphabetical order. Handling that would require sorting CSS // non-alphabetical order. Handling that would require sorting CSS
@ -133,12 +117,25 @@ if (__DEV__) {
// in that browser completely in favor of doing all that work. // in that browser completely in favor of doing all that work.
// See https://github.com/facebook/react/issues/11807 // See https://github.com/facebook/react/issues/11807
canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
}
warnForPropDifference = function ( function validatePropertiesInDevelopment(type: string, props: any) {
if (__DEV__) {
validateARIAProperties(type, props);
validateInputProperties(type, props);
validateUnknownProperties(type, props, {
registrationNameDependencies,
possibleRegistrationNames,
});
}
}
function warnForPropDifference(
propName: string, propName: string,
serverValue: mixed, serverValue: mixed,
clientValue: mixed, clientValue: mixed,
) { ) {
if (__DEV__) {
if (didWarnInvalidHydration) { if (didWarnInvalidHydration) {
return; return;
} }
@ -156,9 +153,11 @@ if (__DEV__) {
JSON.stringify(normalizedServerValue), JSON.stringify(normalizedServerValue),
JSON.stringify(normalizedClientValue), JSON.stringify(normalizedClientValue),
); );
}; }
}
warnForExtraAttributes = function (attributeNames: Set<string>) { function warnForExtraAttributes(attributeNames: Set<string>) {
if (__DEV__) {
if (didWarnInvalidHydration) { if (didWarnInvalidHydration) {
return; return;
} }
@ -168,12 +167,11 @@ if (__DEV__) {
names.push(name); names.push(name);
}); });
console.error('Extra attributes from the server: %s', names); console.error('Extra attributes from the server: %s', names);
}; }
}
warnForInvalidEventListener = function ( function warnForInvalidEventListener(registrationName: string, listener: any) {
registrationName: string, if (__DEV__) {
listener: any,
) {
if (listener === false) { if (listener === false) {
console.error( console.error(
'Expected `%s` listener to be a function, instead got `false`.\n\n' + 'Expected `%s` listener to be a function, instead got `false`.\n\n' +
@ -190,11 +188,13 @@ if (__DEV__) {
typeof listener, typeof listener,
); );
} }
}; }
}
// Parse the HTML and read it back to normalize the HTML string so that it // Parse the HTML and read it back to normalize the HTML string so that it
// can be used for comparison. // can be used for comparison.
normalizeHTML = function (parent: Element, html: string) { function normalizeHTML(parent: Element, html: string) {
if (__DEV__) {
// We could have created a separate document here to avoid // We could have created a separate document here to avoid
// re-initializing custom elements if they exist. But this breaks // re-initializing custom elements if they exist. But this breaks
// how <noscript> is being handled. So we use the same document. // how <noscript> is being handled. So we use the same document.
@ -208,7 +208,7 @@ if (__DEV__) {
); );
testElement.innerHTML = html; testElement.innerHTML = html;
return testElement.innerHTML; return testElement.innerHTML;
}; }
} }
// HTML parsing normalizes CR and CRLF to LF. // HTML parsing normalizes CR and CRLF to LF.

View File

@ -1,25 +0,0 @@
/**
* 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.
*/
/* globals MSApp */
/**
* Create a function which has 'unsafe' privileges (required by windows8 apps)
*/
const createMicrosoftUnsafeLocalFunction = function (func) {
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
return function (arg0, arg1, arg2, arg3) {
MSApp.execUnsafeLocalFunction(function () {
return func(arg0, arg1, arg2, arg3);
});
};
} else {
return func;
}
};
export default createMicrosoftUnsafeLocalFunction;

View File

@ -7,24 +7,15 @@
* @flow * @flow
*/ */
/* globals MSApp */
import {SVG_NAMESPACE} from './DOMNamespaces'; import {SVG_NAMESPACE} from './DOMNamespaces';
import createMicrosoftUnsafeLocalFunction from './createMicrosoftUnsafeLocalFunction';
import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags'; import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
// SVG temp container for IE lacking innerHTML // SVG temp container for IE lacking innerHTML
let reusableSVGContainer: HTMLElement; let reusableSVGContainer: HTMLElement;
/** function setInnerHTMLImpl(
* Set the innerHTML property of a node
*
* @param {DOMElement} node
* @param {string} html
* @internal
*/
const setInnerHTML: (
node: Element,
html: {valueOf(): {toString(): string, ...}, ...},
) => void = createMicrosoftUnsafeLocalFunction(function (
node: Element, node: Element,
html: {valueOf(): {toString(): string, ...}, ...}, html: {valueOf(): {toString(): string, ...}, ...},
): void { ): void {
@ -66,6 +57,26 @@ const setInnerHTML: (
} }
} }
node.innerHTML = (html: any); node.innerHTML = (html: any);
}); }
let setInnerHTML: (
node: Element,
html: {valueOf(): {toString(): string, ...}, ...},
) => void = setInnerHTMLImpl;
// $FlowFixMe[cannot-resolve-name]
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
/**
* Create a function which has 'unsafe' privileges (required by windows8 apps)
*/
setInnerHTML = function (
node: Element,
html: {valueOf(): {toString(): string, ...}, ...},
): void {
// $FlowFixMe[cannot-resolve-name]
return MSApp.execUnsafeLocalFunction(function () {
return setInnerHTMLImpl(node, html);
});
};
}
export default setInnerHTML; export default setInnerHTML;

View File

@ -18,7 +18,7 @@ import {TEXT_NODE} from './HTMLNodeType';
* @param {string} text * @param {string} text
* @internal * @internal
*/ */
const setTextContent = function (node: Element, text: string): void { function setTextContent(node: Element, text: string): void {
if (text) { if (text) {
const firstChild = node.firstChild; const firstChild = node.firstChild;
@ -32,6 +32,6 @@ const setTextContent = function (node: Element, text: string): void {
} }
} }
node.textContent = text; node.textContent = text;
}; }
export default setTextContent; export default setTextContent;

View File

@ -7,12 +7,6 @@
* @flow * @flow
*/ */
type ValidateDOMNesting = (?string, ?string, AncestorInfoDev) => void;
let validateDOMNesting: ValidateDOMNesting = (() => {}: any);
type UpdatedAncestorInfoDev = (?AncestorInfoDev, string) => AncestorInfoDev;
let updatedAncestorInfoDev: UpdatedAncestorInfoDev = (() => {}: any);
type Info = {tag: string}; type Info = {tag: string};
export type AncestorInfoDev = { export type AncestorInfoDev = {
current: ?Info, current: ?Info,
@ -30,20 +24,19 @@ export type AncestorInfoDev = {
containerTagInScope: ?Info, containerTagInScope: ?Info,
}; };
if (__DEV__) { // This validation code was written based on the HTML5 parsing spec:
// This validation code was written based on the HTML5 parsing spec: // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope //
// // Note: this does not catch all invalid nesting, nor does it try to (as it's
// Note: this does not catch all invalid nesting, nor does it try to (as it's // not clear what practical benefit doing so provides); instead, we warn only
// not clear what practical benefit doing so provides); instead, we warn only // for cases where the parser will give a parse tree differing from what React
// for cases where the parser will give a parse tree differing from what React // intended. For example, <b><div></div></b> is invalid but we don't warn
// intended. For example, <b><div></div></b> is invalid but we don't warn // because it still parses correctly; we do warn for other cases like nested
// because it still parses correctly; we do warn for other cases like nested // <p> tags where the beginning of the second element implicitly closes the
// <p> tags where the beginning of the second element implicitly closes the // first, causing a confusing mess.
// first, causing a confusing mess.
// https://html.spec.whatwg.org/multipage/syntax.html#special // https://html.spec.whatwg.org/multipage/syntax.html#special
const specialTags = [ const specialTags = [
'address', 'address',
'applet', 'applet',
'area', 'area',
@ -127,10 +120,10 @@ if (__DEV__) {
'ul', 'ul',
'wbr', 'wbr',
'xmp', 'xmp',
]; ];
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
const inScopeTags = [ const inScopeTags = [
'applet', 'applet',
'caption', 'caption',
'html', 'html',
@ -147,13 +140,13 @@ if (__DEV__) {
'foreignObject', 'foreignObject',
'desc', 'desc',
'title', 'title',
]; ];
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
const buttonScopeTags = inScopeTags.concat(['button']); const buttonScopeTags = __DEV__ ? inScopeTags.concat(['button']) : [];
// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
const impliedEndTags = [ const impliedEndTags = [
'dd', 'dd',
'dt', 'dt',
'li', 'li',
@ -162,9 +155,9 @@ if (__DEV__) {
'p', 'p',
'rp', 'rp',
'rt', 'rt',
]; ];
const emptyAncestorInfoDev: AncestorInfoDev = { const emptyAncestorInfoDev: AncestorInfoDev = {
current: null, current: null,
formTag: null, formTag: null,
@ -177,9 +170,13 @@ if (__DEV__) {
dlItemTagAutoclosing: null, dlItemTagAutoclosing: null,
containerTagInScope: null, containerTagInScope: null,
}; };
updatedAncestorInfoDev = function (oldInfo: ?AncestorInfoDev, tag: string) { function updatedAncestorInfoDev(
oldInfo: ?AncestorInfoDev,
tag: string,
): AncestorInfoDev {
if (__DEV__) {
const ancestorInfo = {...(oldInfo || emptyAncestorInfoDev)}; const ancestorInfo = {...(oldInfo || emptyAncestorInfoDev)};
const info = {tag}; const info = {tag};
@ -234,15 +231,15 @@ if (__DEV__) {
} }
return ancestorInfo; return ancestorInfo;
}; } else {
return (null: any);
}
}
/** /**
* Returns whether * Returns whether
*/ */
const isTagValidWithParent = function ( function isTagValidWithParent(tag: string, parentTag: ?string): boolean {
tag: string,
parentTag: ?string,
): boolean {
// First, let's check if we're in an unusual parsing mode... // First, let's check if we're in an unusual parsing mode...
switch (parentTag) { switch (parentTag) {
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
@ -362,15 +359,15 @@ if (__DEV__) {
} }
return true; return true;
}; }
/** /**
* Returns whether * Returns whether
*/ */
const findInvalidAncestorForTag = function ( function findInvalidAncestorForTag(
tag: string, tag: string,
ancestorInfo: AncestorInfoDev, ancestorInfo: AncestorInfoDev,
): ?Info { ): ?Info {
switch (tag) { switch (tag) {
case 'address': case 'address':
case 'article': case 'article':
@ -432,15 +429,16 @@ if (__DEV__) {
} }
return null; return null;
}; }
const didWarn: {[string]: boolean} = {}; const didWarn: {[string]: boolean} = {};
validateDOMNesting = function ( function validateDOMNesting(
childTag: ?string, childTag: ?string,
childText: ?string, childText: ?string,
ancestorInfo: AncestorInfoDev, ancestorInfo: AncestorInfoDev,
) { ): void {
if (__DEV__) {
ancestorInfo = ancestorInfo || emptyAncestorInfoDev; ancestorInfo = ancestorInfo || emptyAncestorInfoDev;
const parentInfo = ancestorInfo.current; const parentInfo = ancestorInfo.current;
const parentTag = parentInfo && parentInfo.tag; const parentTag = parentInfo && parentInfo.tag;
@ -517,7 +515,7 @@ if (__DEV__) {
ancestorTag, ancestorTag,
); );
} }
}; }
} }
export {updatedAncestorInfoDev, validateDOMNesting}; export {updatedAncestorInfoDev, validateDOMNesting};

View File

@ -16,16 +16,18 @@ import isCustomComponent from './isCustomComponent';
import possibleStandardNames from './possibleStandardNames'; import possibleStandardNames from './possibleStandardNames';
import hasOwnProperty from 'shared/hasOwnProperty'; import hasOwnProperty from 'shared/hasOwnProperty';
let validateProperty = () => {}; const warnedProperties = {};
const EVENT_NAME_REGEX = /^on./;
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
const rARIA = __DEV__
? new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$')
: null;
const rARIACamel = __DEV__
? new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$')
: null;
if (__DEV__) { function validateProperty(tagName, name, value, eventRegistry) {
const warnedProperties = {}; if (__DEV__) {
const EVENT_NAME_REGEX = /^on./;
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
const rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
const rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
validateProperty = function (tagName, name, value, eventRegistry) {
if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
return true; return true;
} }
@ -234,10 +236,10 @@ if (__DEV__) {
} }
return true; return true;
}; }
} }
const warnUnknownProperties = function (type, props, eventRegistry) { function warnUnknownProperties(type, props, eventRegistry) {
if (__DEV__) { if (__DEV__) {
const unknownProps = []; const unknownProps = [];
for (const key in props) { for (const key in props) {
@ -268,7 +270,7 @@ const warnUnknownProperties = function (type, props, eventRegistry) {
); );
} }
} }
}; }
export function validateProperties(type, props, eventRegistry) { export function validateProperties(type, props, eventRegistry) {
if (isCustomComponent(type, props)) { if (isCustomComponent(type, props)) {

View File

@ -5,29 +5,27 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
let warnValidStyle = () => {}; // 'msTransform' is correct, but the other prefixes should be capitalized
const badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
const msPattern = /^-ms-/;
const hyphenPattern = /-(.)/g;
if (__DEV__) { // style values shouldn't contain a semicolon
// 'msTransform' is correct, but the other prefixes should be capitalized const badStyleValueWithSemicolonPattern = /;\s*$/;
const badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
const msPattern = /^-ms-/;
const hyphenPattern = /-(.)/g;
// style values shouldn't contain a semicolon const warnedStyleNames = {};
const badStyleValueWithSemicolonPattern = /;\s*$/; const warnedStyleValues = {};
let warnedForNaNValue = false;
let warnedForInfinityValue = false;
const warnedStyleNames = {}; function camelize(string) {
const warnedStyleValues = {};
let warnedForNaNValue = false;
let warnedForInfinityValue = false;
const camelize = function (string) {
return string.replace(hyphenPattern, function (_, character) { return string.replace(hyphenPattern, function (_, character) {
return character.toUpperCase(); return character.toUpperCase();
}); });
}; }
const warnHyphenatedStyleName = function (name) { function warnHyphenatedStyleName(name) {
if (__DEV__) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return; return;
} }
@ -41,9 +39,11 @@ if (__DEV__) {
// is converted to lowercase `ms`. // is converted to lowercase `ms`.
camelize(name.replace(msPattern, 'ms-')), camelize(name.replace(msPattern, 'ms-')),
); );
}; }
}
const warnBadVendoredStyleName = function (name) { function warnBadVendoredStyleName(name) {
if (__DEV__) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return; return;
} }
@ -54,9 +54,11 @@ if (__DEV__) {
name, name,
name.charAt(0).toUpperCase() + name.slice(1), name.charAt(0).toUpperCase() + name.slice(1),
); );
}; }
}
const warnStyleValueWithSemicolon = function (name, value) { function warnStyleValueWithSemicolon(name, value) {
if (__DEV__) {
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
return; return;
} }
@ -68,9 +70,11 @@ if (__DEV__) {
name, name,
value.replace(badStyleValueWithSemicolonPattern, ''), value.replace(badStyleValueWithSemicolonPattern, ''),
); );
}; }
}
const warnStyleValueIsNaN = function (name, value) { function warnStyleValueIsNaN(name, value) {
if (__DEV__) {
if (warnedForNaNValue) { if (warnedForNaNValue) {
return; return;
} }
@ -80,9 +84,11 @@ if (__DEV__) {
'`NaN` is an invalid value for the `%s` css style property.', '`NaN` is an invalid value for the `%s` css style property.',
name, name,
); );
}; }
}
const warnStyleValueIsInfinity = function (name, value) { function warnStyleValueIsInfinity(name, value) {
if (__DEV__) {
if (warnedForInfinityValue) { if (warnedForInfinityValue) {
return; return;
} }
@ -92,9 +98,11 @@ if (__DEV__) {
'`Infinity` is an invalid value for the `%s` css style property.', '`Infinity` is an invalid value for the `%s` css style property.',
name, name,
); );
}; }
}
warnValidStyle = function (name, value) { function warnValidStyle(name, value) {
if (__DEV__) {
if (name.indexOf('-') > -1) { if (name.indexOf('-') > -1) {
warnHyphenatedStyleName(name); warnHyphenatedStyleName(name);
} else if (badVendoredStyleNamePattern.test(name)) { } else if (badVendoredStyleNamePattern.test(name)) {
@ -110,7 +118,7 @@ if (__DEV__) {
warnStyleValueIsInfinity(name, value); warnStyleValueIsInfinity(name, value);
} }
} }
}; }
} }
export default warnValidStyle; export default warnValidStyle;

View File

@ -392,7 +392,7 @@ function executeDispatchesInOrder(event) {
* @param {?object} event Synthetic event to be dispatched. * @param {?object} event Synthetic event to be dispatched.
* @private * @private
*/ */
const executeDispatchesAndRelease = function (event /* ReactSyntheticEvent */) { function executeDispatchesAndRelease(event /* ReactSyntheticEvent */) {
if (event) { if (event) {
executeDispatchesInOrder(event); executeDispatchesInOrder(event);
@ -400,7 +400,7 @@ const executeDispatchesAndRelease = function (event /* ReactSyntheticEvent */) {
event.constructor.release(event); event.constructor.release(event);
} }
} }
}; }
function isInteractive(tag) { function isInteractive(tag) {
return ( return (

View File

@ -44,13 +44,13 @@ const EMPTY_NATIVE_EVENT = (({}: any): AnyNativeEvent);
* @return {Array<Touch>} Subsequence of touch objects. * @return {Array<Touch>} Subsequence of touch objects.
*/ */
// $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-local-annot]
const touchSubsequence = function (touches, indices) { function touchSubsequence(touches, indices) {
const ret = []; const ret = [];
for (let i = 0; i < indices.length; i++) { for (let i = 0; i < indices.length; i++) {
ret.push(touches[indices[i]]); ret.push(touches[indices[i]]);
} }
return ret; return ret;
}; }
/** /**
* TODO: Pool all of this. * TODO: Pool all of this.
@ -63,7 +63,7 @@ const touchSubsequence = function (touches, indices) {
* @param {Array<number>} indices Indices to remove from `touches`. * @param {Array<number>} indices Indices to remove from `touches`.
* @return {Array<Touch>} Subsequence of removed touch objects. * @return {Array<Touch>} Subsequence of removed touch objects.
*/ */
const removeTouchesAtIndices = function ( function removeTouchesAtIndices(
touches: Array<Object>, touches: Array<Object>,
indices: Array<number>, indices: Array<number>,
): Array<Object> { ): Array<Object> {
@ -85,7 +85,7 @@ const removeTouchesAtIndices = function (
} }
temp.length = fillAt; temp.length = fillAt;
return rippedOut; return rippedOut;
}; }
/** /**
* Internal version of `receiveEvent` in terms of normalized (non-tag) * Internal version of `receiveEvent` in terms of normalized (non-tag)

View File

@ -28,19 +28,8 @@ if (__DEV__) {
Object.freeze(emptyObject); Object.freeze(emptyObject);
} }
let createHierarchy; // $FlowFixMe[missing-local-annot]
let getHostNode; function createHierarchy(fiberHierarchy) {
let getHostProps;
let lastNonHostInstance;
let getInspectorDataForInstance: (
closestInstance: Fiber | null,
) => InspectorData;
let getOwnerHierarchy;
let traverseOwnerTreeUp: (hierarchy: Array<$FlowFixMe>, instance: any) => void;
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
// $FlowFixMe[missing-local-annot]
createHierarchy = function (fiberHierarchy) {
return fiberHierarchy.map(fiber => ({ return fiberHierarchy.map(fiber => ({
name: getComponentNameFromType(fiber.type), name: getComponentNameFromType(fiber.type),
getInspectorData: findNodeHandle => { getInspectorData: findNodeHandle => {
@ -67,10 +56,11 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
}; };
}, },
})); }));
}; }
// $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-local-annot]
getHostNode = function (fiber: Fiber | null, findNodeHandle) { function getHostNode(fiber: Fiber | null, findNodeHandle) {
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
let hostNode; let hostNode;
// look for children first for the hostNode // look for children first for the hostNode
// as composite fibers do not have a hostNode // as composite fibers do not have a hostNode
@ -84,20 +74,22 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
fiber = fiber.child; fiber = fiber.child;
} }
return null; return null;
}; }
}
// $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-local-annot]
getHostProps = function (fiber) { function getHostProps(fiber) {
const host = findCurrentHostFiber(fiber); const host = findCurrentHostFiber(fiber);
if (host) { if (host) {
return host.memoizedProps || emptyObject; return host.memoizedProps || emptyObject;
} }
return emptyObject; return emptyObject;
}; }
getInspectorDataForInstance = function ( function getInspectorDataForInstance(
closestInstance: Fiber | null, closestInstance: Fiber | null,
): InspectorData { ): InspectorData {
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
// Handle case where user clicks outside of ReactNative // Handle case where user clicks outside of ReactNative
if (!closestInstance) { if (!closestInstance) {
return { return {
@ -123,16 +115,19 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
selectedIndex, selectedIndex,
source, source,
}; };
}; } else {
return (null: any);
}
}
getOwnerHierarchy = function (instance: any) { function getOwnerHierarchy(instance: any) {
const hierarchy: Array<$FlowFixMe> = []; const hierarchy: Array<$FlowFixMe> = [];
traverseOwnerTreeUp(hierarchy, instance); traverseOwnerTreeUp(hierarchy, instance);
return hierarchy; return hierarchy;
}; }
// $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-local-annot]
lastNonHostInstance = function (hierarchy) { function lastNonHostInstance(hierarchy) {
for (let i = hierarchy.length - 1; i > 1; i--) { for (let i = hierarchy.length - 1; i > 1; i--) {
const instance = hierarchy[i]; const instance = hierarchy[i];
@ -141,28 +136,23 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
} }
} }
return hierarchy[0]; return hierarchy[0];
}; }
// $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-local-annot]
traverseOwnerTreeUp = function (hierarchy, instance: any): void { function traverseOwnerTreeUp(
hierarchy: Array<$FlowFixMe>,
instance: any,
): void {
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
if (instance) { if (instance) {
hierarchy.unshift(instance); hierarchy.unshift(instance);
traverseOwnerTreeUp(hierarchy, instance._debugOwner); traverseOwnerTreeUp(hierarchy, instance._debugOwner);
} }
}; }
} }
let getInspectorDataForViewTag: (viewTag: number) => Object; function getInspectorDataForViewTag(viewTag: number): Object {
let getInspectorDataForViewAtPoint: ( if (__DEV__) {
findNodeHandle: (componentOrHandle: any) => ?number,
inspectedView: Object,
locationX: number,
locationY: number,
callback: (viewData: TouchedViewDataAtPoint) => mixed,
) => void;
if (__DEV__) {
getInspectorDataForViewTag = function (viewTag: number): Object {
const closestInstance = getClosestInstanceFromNode(viewTag); const closestInstance = getClosestInstanceFromNode(viewTag);
// Handle case where user clicks outside of ReactNative // Handle case where user clicks outside of ReactNative
@ -189,15 +179,21 @@ if (__DEV__) {
selectedIndex, selectedIndex,
source, source,
}; };
}; } else {
throw new Error(
'getInspectorDataForViewTag() is not available in production',
);
}
}
getInspectorDataForViewAtPoint = function ( function getInspectorDataForViewAtPoint(
findNodeHandle: (componentOrHandle: any) => ?number, findNodeHandle: (componentOrHandle: any) => ?number,
inspectedView: Object, inspectedView: Object,
locationX: number, locationX: number,
locationY: number, locationY: number,
callback: (viewData: TouchedViewDataAtPoint) => mixed, callback: (viewData: TouchedViewDataAtPoint) => mixed,
): void { ): void {
if (__DEV__) {
let closestInstance = null; let closestInstance = null;
const fabricInstanceHandle = const fabricInstanceHandle =
@ -271,25 +267,11 @@ if (__DEV__) {
return; return;
} }
}; } else {
} else {
getInspectorDataForViewTag = () => {
throw new Error(
'getInspectorDataForViewTag() is not available in production',
);
};
getInspectorDataForViewAtPoint = (
findNodeHandle: (componentOrHandle: any) => ?number,
inspectedView: Object,
locationX: number,
locationY: number,
callback: (viewData: TouchedViewDataAtPoint) => mixed,
): void => {
throw new Error( throw new Error(
'getInspectorDataForViewAtPoint() is not available in production.', 'getInspectorDataForViewAtPoint() is not available in production.',
); );
}; }
} }
export { export {

View File

@ -15,7 +15,7 @@ type Options = {+unsafelyIgnoreFunctions?: boolean};
/* /*
* @returns {bool} true if different, false if equal * @returns {bool} true if different, false if equal
*/ */
const deepDiffer = function ( function deepDiffer(
one: any, one: any,
two: any, two: any,
maxDepthOrOptions: Options | number = -1, maxDepthOrOptions: Options | number = -1,
@ -79,6 +79,6 @@ const deepDiffer = function (
} }
} }
return false; return false;
}; }
module.exports = deepDiffer; module.exports = deepDiffer;

View File

@ -9,6 +9,6 @@
// TODO: move into react or fbjs // TODO: move into react or fbjs
const deepFreezeAndThrowOnMutationInDev = function () {}; function deepFreezeAndThrowOnMutationInDev() {}
module.exports = deepFreezeAndThrowOnMutationInDev; module.exports = deepFreezeAndThrowOnMutationInDev;

View File

@ -9,6 +9,6 @@
// TODO: Move flattenStyle into react // TODO: Move flattenStyle into react
const flattenStyle = function () {}; function flattenStyle() {}
module.exports = flattenStyle; module.exports = flattenStyle;

View File

@ -25,7 +25,7 @@ let eventQueue: ?(Array<ReactSyntheticEvent> | ReactSyntheticEvent) = null;
* @param {?object} event Synthetic event to be dispatched. * @param {?object} event Synthetic event to be dispatched.
* @private * @private
*/ */
const executeDispatchesAndRelease = function (event: ReactSyntheticEvent) { function executeDispatchesAndRelease(event: ReactSyntheticEvent) {
if (event) { if (event) {
executeDispatchesInOrder(event); executeDispatchesInOrder(event);
@ -33,11 +33,11 @@ const executeDispatchesAndRelease = function (event: ReactSyntheticEvent) {
event.constructor.release(event); event.constructor.release(event);
} }
} }
}; }
// $FlowFixMe[missing-local-annot] // $FlowFixMe[missing-local-annot]
const executeDispatchesAndReleaseTopLevel = function (e) { function executeDispatchesAndReleaseTopLevel(e) {
return executeDispatchesAndRelease(e); return executeDispatchesAndRelease(e);
}; }
export function runEventsInBatch( export function runEventsInBatch(
events: Array<ReactSyntheticEvent> | ReactSyntheticEvent | null, events: Array<ReactSyntheticEvent> | ReactSyntheticEvent | null,

View File

@ -30,9 +30,8 @@ export function setComponentTree(
} }
} }
let validateEventDispatches; function validateEventDispatches(event) {
if (__DEV__) { if (__DEV__) {
validateEventDispatches = function (event) {
const dispatchListeners = event._dispatchListeners; const dispatchListeners = event._dispatchListeners;
const dispatchInstances = event._dispatchInstances; const dispatchInstances = event._dispatchInstances;
@ -53,7 +52,7 @@ if (__DEV__) {
if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
console.error('EventPluginUtils: Invalid `event`.'); console.error('EventPluginUtils: Invalid `event`.');
} }
}; }
} }
/** /**

View File

@ -44,7 +44,7 @@ let responderInst = null;
*/ */
let trackedTouchCount = 0; let trackedTouchCount = 0;
const changeResponder = function (nextResponderInst, blockHostResponder) { function changeResponder(nextResponderInst, blockHostResponder) {
const oldResponderInst = responderInst; const oldResponderInst = responderInst;
responderInst = nextResponderInst; responderInst = nextResponderInst;
if (ResponderEventPlugin.GlobalResponderHandler !== null) { if (ResponderEventPlugin.GlobalResponderHandler !== null) {
@ -54,7 +54,7 @@ const changeResponder = function (nextResponderInst, blockHostResponder) {
blockHostResponder, blockHostResponder,
); );
} }
}; }
const eventTypes = { const eventTypes = {
/** /**

View File

@ -224,7 +224,7 @@ function FiberNode(
// is faster. // is faster.
// 5) It should be easy to port this to a C struct and keep a C implementation // 5) It should be easy to port this to a C struct and keep a C implementation
// compatible. // compatible.
const createFiber = function ( function createFiber(
tag: WorkTag, tag: WorkTag,
pendingProps: mixed, pendingProps: mixed,
key: null | string, key: null | string,
@ -232,7 +232,7 @@ const createFiber = function (
): Fiber { ): Fiber {
// $FlowFixMe: the shapes are exact here but Flow doesn't like constructors // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
return new FiberNode(tag, pendingProps, key, mode); return new FiberNode(tag, pendingProps, key, mode);
}; }
function shouldConstruct(Component: Function) { function shouldConstruct(Component: Function) {
const prototype = Component.prototype; const prototype = Component.prototype;

View File

@ -85,11 +85,10 @@ let didWarnAboutUninitializedState;
let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
let didWarnAboutLegacyLifecyclesAndDerivedState; let didWarnAboutLegacyLifecyclesAndDerivedState;
let didWarnAboutUndefinedDerivedState; let didWarnAboutUndefinedDerivedState;
let warnOnUndefinedDerivedState;
let warnOnInvalidCallback;
let didWarnAboutDirectlyAssigningPropsToState; let didWarnAboutDirectlyAssigningPropsToState;
let didWarnAboutContextTypeAndContextTypes; let didWarnAboutContextTypeAndContextTypes;
let didWarnAboutInvalidateContextType; let didWarnAboutInvalidateContextType;
let didWarnOnInvalidCallback;
if (__DEV__) { if (__DEV__) {
didWarnAboutStateAssignmentForComponent = new Set<string>(); didWarnAboutStateAssignmentForComponent = new Set<string>();
@ -100,38 +99,7 @@ if (__DEV__) {
didWarnAboutUndefinedDerivedState = new Set<string>(); didWarnAboutUndefinedDerivedState = new Set<string>();
didWarnAboutContextTypeAndContextTypes = new Set<string>(); didWarnAboutContextTypeAndContextTypes = new Set<string>();
didWarnAboutInvalidateContextType = new Set<string>(); didWarnAboutInvalidateContextType = new Set<string>();
didWarnOnInvalidCallback = new Set<string>();
const didWarnOnInvalidCallback = new Set<string>();
warnOnInvalidCallback = function (callback: mixed, callerName: string) {
if (callback === null || typeof callback === 'function') {
return;
}
const key = callerName + '_' + (callback: any);
if (!didWarnOnInvalidCallback.has(key)) {
didWarnOnInvalidCallback.add(key);
console.error(
'%s(...): Expected the last optional `callback` argument to be a ' +
'function. Instead received: %s.',
callerName,
callback,
);
}
};
warnOnUndefinedDerivedState = function (type: any, partialState: any) {
if (partialState === undefined) {
const componentName = getComponentNameFromType(type) || 'Component';
if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
didWarnAboutUndefinedDerivedState.add(componentName);
console.error(
'%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
'You have returned undefined.',
componentName,
);
}
}
};
// This is so gross but it's at least non-critical and can be removed if // This is so gross but it's at least non-critical and can be removed if
// it causes problems. This is meant to give a nicer error message for // it causes problems. This is meant to give a nicer error message for
@ -154,6 +122,40 @@ if (__DEV__) {
Object.freeze(fakeInternalInstance); Object.freeze(fakeInternalInstance);
} }
function warnOnInvalidCallback(callback: mixed, callerName: string) {
if (__DEV__) {
if (callback === null || typeof callback === 'function') {
return;
}
const key = callerName + '_' + (callback: any);
if (!didWarnOnInvalidCallback.has(key)) {
didWarnOnInvalidCallback.add(key);
console.error(
'%s(...): Expected the last optional `callback` argument to be a ' +
'function. Instead received: %s.',
callerName,
callback,
);
}
}
}
function warnOnUndefinedDerivedState(type: any, partialState: any) {
if (__DEV__) {
if (partialState === undefined) {
const componentName = getComponentNameFromType(type) || 'Component';
if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
didWarnAboutUndefinedDerivedState.add(componentName);
console.error(
'%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
'You have returned undefined.',
componentName,
);
}
}
}
}
function applyDerivedStateFromProps( function applyDerivedStateFromProps(
workInProgress: Fiber, workInProgress: Fiber,
ctor: any, ctor: any,

View File

@ -253,10 +253,7 @@ export function reportUncaughtErrorInDEV(error: mixed) {
} }
} }
const callComponentWillUnmountWithTimer = function ( function callComponentWillUnmountWithTimer(current: Fiber, instance: any) {
current: Fiber,
instance: any,
) {
instance.props = current.memoizedProps; instance.props = current.memoizedProps;
instance.state = current.memoizedState; instance.state = current.memoizedState;
if (shouldProfile(current)) { if (shouldProfile(current)) {
@ -269,7 +266,7 @@ const callComponentWillUnmountWithTimer = function (
} else { } else {
instance.componentWillUnmount(); instance.componentWillUnmount();
} }
}; }
// Capture errors so they don't interrupt unmounting. // Capture errors so they don't interrupt unmounting.
function safelyCallComponentWillUnmount( function safelyCallComponentWillUnmount(

View File

@ -24,11 +24,10 @@ let didWarnAboutUninitializedState;
let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
let didWarnAboutLegacyLifecyclesAndDerivedState; let didWarnAboutLegacyLifecyclesAndDerivedState;
let didWarnAboutUndefinedDerivedState; let didWarnAboutUndefinedDerivedState;
let warnOnUndefinedDerivedState;
let warnOnInvalidCallback;
let didWarnAboutDirectlyAssigningPropsToState; let didWarnAboutDirectlyAssigningPropsToState;
let didWarnAboutContextTypeAndContextTypes; let didWarnAboutContextTypeAndContextTypes;
let didWarnAboutInvalidateContextType; let didWarnAboutInvalidateContextType;
let didWarnOnInvalidCallback;
if (__DEV__) { if (__DEV__) {
didWarnAboutUninitializedState = new Set<string>(); didWarnAboutUninitializedState = new Set<string>();
@ -38,10 +37,11 @@ if (__DEV__) {
didWarnAboutUndefinedDerivedState = new Set<string>(); didWarnAboutUndefinedDerivedState = new Set<string>();
didWarnAboutContextTypeAndContextTypes = new Set<mixed>(); didWarnAboutContextTypeAndContextTypes = new Set<mixed>();
didWarnAboutInvalidateContextType = new Set<mixed>(); didWarnAboutInvalidateContextType = new Set<mixed>();
didWarnOnInvalidCallback = new Set<string>();
}
const didWarnOnInvalidCallback = new Set<string>(); function warnOnInvalidCallback(callback: mixed, callerName: string) {
if (__DEV__) {
warnOnInvalidCallback = function (callback: mixed, callerName: string) {
if (callback === null || typeof callback === 'function') { if (callback === null || typeof callback === 'function') {
return; return;
} }
@ -55,9 +55,11 @@ if (__DEV__) {
callback, callback,
); );
} }
}; }
}
warnOnUndefinedDerivedState = function (type: any, partialState: any) { function warnOnUndefinedDerivedState(type: any, partialState: any) {
if (__DEV__) {
if (partialState === undefined) { if (partialState === undefined) {
const componentName = getComponentNameFromType(type) || 'Component'; const componentName = getComponentNameFromType(type) || 'Component';
if (!didWarnAboutUndefinedDerivedState.has(componentName)) { if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
@ -69,7 +71,7 @@ if (__DEV__) {
); );
} }
} }
}; }
} }
function warnNoop( function warnNoop(

View File

@ -145,7 +145,7 @@ function warnIfStringRefCannotBeAutoConverted(config) {
* indicating filename, line number, and/or other information. * indicating filename, line number, and/or other information.
* @internal * @internal
*/ */
const ReactElement = function (type, key, ref, self, source, owner, props) { function ReactElement(type, key, ref, self, source, owner, props) {
const element = { const element = {
// This tag allows us to uniquely identify this as a React Element // This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE, $$typeof: REACT_ELEMENT_TYPE,
@ -199,7 +199,7 @@ const ReactElement = function (type, key, ref, self, source, owner, props) {
} }
return element; return element;
}; }
/** /**
* https://github.com/reactjs/rfcs/pull/107 * https://github.com/reactjs/rfcs/pull/107

View File

@ -145,7 +145,7 @@ function defineRefPropWarningGetter(props, displayName) {
* indicating filename, line number, and/or other information. * indicating filename, line number, and/or other information.
* @internal * @internal
*/ */
const ReactElement = function (type, key, ref, self, source, owner, props) { function ReactElement(type, key, ref, self, source, owner, props) {
const element = { const element = {
// This tag allows us to uniquely identify this as a React Element // This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE, $$typeof: REACT_ELEMENT_TYPE,
@ -199,7 +199,7 @@ const ReactElement = function (type, key, ref, self, source, owner, props) {
} }
return element; return element;
}; }
/** /**
* https://github.com/reactjs/rfcs/pull/107 * https://github.com/reactjs/rfcs/pull/107

View File

@ -16,7 +16,7 @@ if (typeof ReactFbErrorUtils.invokeGuardedCallback !== 'function') {
); );
} }
const invokeGuardedCallbackImpl = function <A, B, C, D, E, F, Context>( function invokeGuardedCallbackImpl<A, B, C, D, E, F, Context>(
name: string | null, name: string | null,
func: (a: A, b: B, c: C, d: D, e: E, f: F) => mixed, func: (a: A, b: B, c: C, d: D, e: E, f: F) => mixed,
context: Context, context: Context,
@ -29,6 +29,6 @@ const invokeGuardedCallbackImpl = function <A, B, C, D, E, F, Context>(
) { ) {
// This will call `this.onError(err)` if an error was caught. // This will call `this.onError(err)` if an error was caught.
ReactFbErrorUtils.invokeGuardedCallback.apply(this, arguments); ReactFbErrorUtils.invokeGuardedCallback.apply(this, arguments);
}; }
export default invokeGuardedCallbackImpl; export default invokeGuardedCallbackImpl;