Compare commits

..
Author SHA1 Message Date
CodemodService Bot 6a015b7832 Fix CQS signal readability-implicit-bool-conversion in xplat/js/react-native-github/packages
Reviewed By: rshest

Differential Revision: D81565980
2025-09-03 06:07:10 -07:00
220 changed files with 1078 additions and 5458 deletions
+6 -1
View File
@@ -75,6 +75,11 @@ module.system.haste.module_ref_prefix=m#
react.runtime=automatic
experimental.only_support_flow_fixme_and_expected_error=true
experimental.require_suppression_with_error_code=true
experimental.invariant_subtyping_error_message_improvement=true
experimental.natural_inference.local_object_literals.followup_fix=true
ban_spread_key_props=true
[lints]
@@ -98,4 +103,4 @@ untyped-import
untyped-type-import
[version]
^0.281.0
^0.280.0
@@ -188,7 +188,6 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
status: 201,
json: () =>
Promise.resolve({
id: 1,
html_url:
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
}),
@@ -209,11 +208,9 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
body: fetchBody,
},
);
expect(response).toEqual({
id: 1,
html_url:
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
});
expect(response).toEqual(
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
);
});
it('creates a draft release for prerelease on GitHub', async () => {
@@ -241,7 +238,6 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
status: 201,
json: () =>
Promise.resolve({
id: 1,
html_url:
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
}),
@@ -262,11 +258,9 @@ View the whole changelog in the [CHANGELOG.md file](https://github.com/facebook/
body: fetchBody,
},
);
expect(response).toEqual({
id: 1,
html_url:
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
});
expect(response).toEqual(
'https://github.com/facebook/react-native/releases/tag/v0.77.1',
);
});
it('throws if the post failes', async () => {
@@ -101,11 +101,7 @@ async function _createDraftReleaseOnGitHub(version, body, latest, token) {
}
const data = await response.json();
const {html_url, id} = data;
return {
html_url,
id,
};
return data.html_url;
}
function moveToChangelogBranch(version) {
@@ -128,8 +124,7 @@ async function createDraftRelease(version, latest, token) {
latest,
token,
);
log(`Created draft release: ${release.html_url}, ID ${release.id}`);
return release;
log(`Created draft release: ${release}`);
}
module.exports = {
+1 -16
View File
@@ -21,24 +21,9 @@ jobs:
git config --local user.name "React Native Bot"
- name: Create draft release
uses: actions/github-script@v6
id: create-draft-release
with:
script: |
const {createDraftRelease} = require('./.github/workflow-scripts/createDraftRelease.js');
const version = '${{ github.ref_name }}';
const {isLatest} = require('./.github/workflow-scripts/publishTemplate.js');
return (await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}')).id;
result-encoding: string
- name: Upload release assets for DotSlash
uses: actions/github-script@v6
env:
RELEASE_ID: ${{ steps.create-draft-release.outputs.result }}
with:
script: |
const {uploadReleaseAssetsForDotSlashFiles} = require('./scripts/releases/upload-release-assets-for-dotslash.js');
const version = '${{ github.ref_name }}';
await uploadReleaseAssetsForDotSlashFiles({
version,
token: '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}',
releaseId: process.env.RELEASE_ID,
});
await createDraftRelease(version, isLatest(), '${{secrets.REACT_NATIVE_BOT_GITHUB_TOKEN}}');
@@ -1,48 +0,0 @@
name: Validate DotSlash Artifacts
on:
workflow_dispatch:
release:
types: [published]
push:
branches:
- main
paths:
- packages/debugger-shell/bin/react-native-devtools
- "scripts/releases/**"
- package.json
- yarn.lock
pull_request:
branches:
- main
paths:
- packages/debugger-shell/bin/react-native-devtools
- "scripts/releases/**"
- package.json
- yarn.lock
# Same time as the nightly build: 2:15 AM UTC
schedule:
- cron: "15 2 * * *"
jobs:
validate-dotslash-artifacts:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Install dependencies
uses: ./.github/actions/yarn-install
- name: Configure Git
shell: bash
run: |
git config --local user.email "bot@reactnative.dev"
git config --local user.name "React Native Bot"
- name: Validate DotSlash artifacts
uses: actions/github-script@v6
with:
script: |
const {validateDotSlashArtifacts} = require('./scripts/releases/validate-dotslash-artifacts.js');
await validateDotSlashArtifacts();
+2 -5
View File
@@ -17,13 +17,10 @@
<img src="https://img.shields.io/npm/v/react-native?color=brightgreen&label=npm%20package" alt="Current npm package version." />
</a>
<a href="https://reactnative.dev/docs/contributing">
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs are welcome!" />
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome!" />
</a>
<a href="https://twitter.com/intent/follow?screen_name=reactnative">
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative on X" />
</a>
<a href="https://bsky.app/profile/reactnative.dev">
<img src="https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff" alt="Follow @reactnative.dev on Bluesky" />
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative" />
</a>
</p>
-46
View File
@@ -1,46 +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.
*
* @flow strict-local
* @format
*/
declare module '@expo/spawn-async' {
type SpawnOptions = {
cwd?: string,
env?: Object,
argv0?: string,
stdio?: string | Array<any>,
detached?: boolean,
uid?: number,
gid?: number,
shell?: boolean | string,
windowsVerbatimArguments?: boolean,
windowsHide?: boolean,
encoding?: string,
ignoreStdio?: boolean,
};
declare class SpawnPromise<T> extends Promise<T> {
child: child_process$ChildProcess;
}
type SpawnResult = {
pid?: number,
output: string[],
stdout: string,
stderr: string,
status: number | null,
signal: string | null,
};
declare function spawnAsync(
command: string,
args?: $ReadOnlyArray<string>,
options?: SpawnOptions,
): SpawnPromise<SpawnResult>;
declare module.exports: typeof spawnAsync;
}
-61
View File
@@ -1,61 +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.
*
* @flow strict-local
* @format
*/
// Partial types for Octokit based on the usage in react-native-github
declare module '@octokit/rest' {
declare class Octokit {
constructor(options?: {auth?: string, ...}): this;
repos: $ReadOnly<{
listReleaseAssets: (
params: $ReadOnly<{
owner: string,
repo: string,
release_id: string,
}>,
) => Promise<{
data: Array<{
id: string,
name: string,
...
}>,
...
}>,
uploadReleaseAsset: (
params: $ReadOnly<{
owner: string,
repo: string,
release_id: string,
name: string,
data: Buffer,
headers: $ReadOnly<{
'content-type': string,
...
}>,
...
}>,
) => Promise<{
data: {
browser_download_url: string,
...
},
...
}>,
deleteReleaseAsset: (params: {
owner: string,
repo: string,
asset_id: string,
...
}) => Promise<mixed>,
}>;
}
declare export {Octokit};
}
-13
View File
@@ -1,13 +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.
*
* @flow strict-local
* @format
*/
declare module 'fb-dotslash' {
declare module.exports: string;
}
-421
View File
@@ -1,421 +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.
*
* @flow strict-local
* @format
*/
declare module 'jsonc-parser' {
/**
* Creates a JSON scanner on the given text.
* If ignoreTrivia is set, whitespaces or comments are ignored.
*/
declare export const createScanner: (
text: string,
ignoreTrivia?: boolean,
) => JSONScanner;
export type ScanError = number;
export type SyntaxKind = number;
/**
* The scanner object, representing a JSON scanner at a position in the input string.
*/
export type JSONScanner = $ReadOnly<{
/**
* Sets the scan position to a new offset. A call to 'scan' is needed to get the first token.
*/
setPosition(pos: number): void,
/**
* Read the next token. Returns the token code.
*/
scan(): SyntaxKind,
/**
* Returns the zero-based current scan position, which is after the last read token.
*/
getPosition(): number,
/**
* Returns the last read token.
*/
getToken(): SyntaxKind,
/**
* Returns the last read token value. The value for strings is the decoded string content. For numbers it's of type number, for boolean it's true or false.
*/
getTokenValue(): string,
/**
* The zero-based start offset of the last read token.
*/
getTokenOffset(): number,
/**
* The length of the last read token.
*/
getTokenLength(): number,
/**
* The zero-based start line number of the last read token.
*/
getTokenStartLine(): number,
/**
* The zero-based start character (column) of the last read token.
*/
getTokenStartCharacter(): number,
/**
* An error code of the last scan.
*/
getTokenError(): ScanError,
}>;
/**
* For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index.
*/
declare export const getLocation: (
text: string,
position: number,
) => Location;
/**
* Parses the given text and returns the object the JSON content represents. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
* Therefore, always check the errors list to find out if the input was valid.
*/
declare export const parse: (
text: string,
errors?: ParseError[],
options?: ParseOptions,
) => any;
/**
* Parses the given text and returns a tree representation the JSON content. On invalid input, the parser tries to be as fault tolerant as possible, but still return a result.
*/
declare export const parseTree: (
text: string,
errors?: ParseError[],
options?: ParseOptions,
) => Node | void;
/**
* Finds the node at the given path in a JSON DOM.
*/
declare export const findNodeAtLocation: (
root: Node,
path: JSONPath,
) => Node | void;
/**
* Finds the innermost node at the given offset. If includeRightBound is set, also finds nodes that end at the given offset.
*/
declare export const findNodeAtOffset: (
root: Node,
offset: number,
includeRightBound?: boolean,
) => Node | void;
/**
* Gets the JSON path of the given JSON DOM node
*/
declare export const getNodePath: (node: Node) => JSONPath;
/**
* Evaluates the JavaScript object of the given JSON DOM node
*/
declare export const getNodeValue: (node: Node) => any;
/**
* Parses the given text and invokes the visitor functions for each object, array and literal reached.
*/
declare export const visit: (
text: string,
visitor: JSONVisitor,
options?: ParseOptions,
) => any;
/**
* Takes JSON with JavaScript-style comments and remove
* them. Optionally replaces every none-newline character
* of comments with a replaceCharacter
*/
declare export const stripComments: (
text: string,
replaceCh?: string,
) => string;
export type ParseError = {
error: ParseErrorCode,
offset: number,
length: number,
};
export type ParseErrorCode = number;
declare export function printParseErrorCode(
code: ParseErrorCode,
):
| 'InvalidSymbol'
| 'InvalidNumberFormat'
| 'PropertyNameExpected'
| 'ValueExpected'
| 'ColonExpected'
| 'CommaExpected'
| 'CloseBraceExpected'
| 'CloseBracketExpected'
| 'EndOfFileExpected'
| 'InvalidCommentToken'
| 'UnexpectedEndOfComment'
| 'UnexpectedEndOfString'
| 'UnexpectedEndOfNumber'
| 'InvalidUnicode'
| 'InvalidEscapeCharacter'
| 'InvalidCharacter'
| '<unknown ParseErrorCode>';
export type NodeType =
| 'object'
| 'array'
| 'property'
| 'string'
| 'number'
| 'boolean'
| 'null';
export type Node = {
type: NodeType,
value?: any,
offset: number,
length: number,
colonOffset?: number,
parent?: Node,
children?: Node[],
};
/**
* A {@linkcode JSONPath} segment. Either a string representing an object property name
* or a number (starting at 0) for array indices.
*/
export type Segment = string | number;
export type JSONPath = Segment[];
export type Location = {
/**
* The previous property key or literal value (string, number, boolean or null) or undefined.
*/
previousNode?: Node,
/**
* The path describing the location in the JSON document. The path consists of a sequence of strings
* representing an object property or numbers for array indices.
*/
path: JSONPath,
/**
* Matches the locations path against a pattern consisting of strings (for properties) and numbers (for array indices).
* '*' will match a single segment of any property name or index.
* '**' will match a sequence of segments of any property name or index, or no segment.
*/
matches: (patterns: JSONPath) => boolean,
/**
* If set, the location's offset is at a property key.
*/
isAtPropertyKey: boolean,
};
export type ParseOptions = {
disallowComments?: boolean,
allowTrailingComma?: boolean,
allowEmptyContent?: boolean,
};
/**
* Visitor called by {@linkcode visit} when parsing JSON.
*
* The visitor functions have the following common parameters:
* - `offset`: Global offset within the JSON document, starting at 0
* - `startLine`: Line number, starting at 0
* - `startCharacter`: Start character (column) within the current line, starting at 0
*
* Additionally some functions have a `pathSupplier` parameter which can be used to obtain the
* current `JSONPath` within the document.
*/
export type JSONVisitor = {
/**
* Invoked when an open brace is encountered and an object is started. The offset and length represent the location of the open brace.
*/
onObjectBegin?: (
offset: number,
length: number,
startLine: number,
startCharacter: number,
pathSupplier: () => JSONPath,
) => void,
/**
* Invoked when a property is encountered. The offset and length represent the location of the property name.
* The `JSONPath` created by the `pathSupplier` refers to the enclosing JSON object, it does not include the
* property name yet.
*/
onObjectProperty?: (
property: string,
offset: number,
length: number,
startLine: number,
startCharacter: number,
pathSupplier: () => JSONPath,
) => void,
/**
* Invoked when a closing brace is encountered and an object is completed. The offset and length represent the location of the closing brace.
*/
onObjectEnd?: (
offset: number,
length: number,
startLine: number,
startCharacter: number,
) => void,
/**
* Invoked when an open bracket is encountered. The offset and length represent the location of the open bracket.
*/
onArrayBegin?: (
offset: number,
length: number,
startLine: number,
startCharacter: number,
pathSupplier: () => JSONPath,
) => void,
/**
* Invoked when a closing bracket is encountered. The offset and length represent the location of the closing bracket.
*/
onArrayEnd?: (
offset: number,
length: number,
startLine: number,
startCharacter: number,
) => void,
/**
* Invoked when a literal value is encountered. The offset and length represent the location of the literal value.
*/
onLiteralValue?: (
value: any,
offset: number,
length: number,
startLine: number,
startCharacter: number,
pathSupplier: () => JSONPath,
) => void,
/**
* Invoked when a comma or colon separator is encountered. The offset and length represent the location of the separator.
*/
onSeparator?: (
character: string,
offset: number,
length: number,
startLine: number,
startCharacter: number,
) => void,
/**
* When comments are allowed, invoked when a line or block comment is encountered. The offset and length represent the location of the comment.
*/
onComment?: (
offset: number,
length: number,
startLine: number,
startCharacter: number,
) => void,
/**
* Invoked on an error.
*/
onError?: (
error: ParseErrorCode,
offset: number,
length: number,
startLine: number,
startCharacter: number,
) => void,
};
/**
* An edit result describes a textual edit operation. It is the result of a {@linkcode format} and {@linkcode modify} operation.
* It consist of one or more edits describing insertions, replacements or removals of text segments.
* * The offsets of the edits refer to the original state of the document.
* * No two edits change or remove the same range of text in the original document.
* * Multiple edits can have the same offset if they are multiple inserts, or an insert followed by a remove or replace.
* * The order in the array defines which edit is applied first.
* To apply an edit result use {@linkcode applyEdits}.
* In general multiple EditResults must not be concatenated because they might impact each other, producing incorrect or malformed JSON data.
*/
export type EditResult = Edit[];
/**
* Represents a text modification
*/
export type Edit = {
/**
* The start offset of the modification.
*/
offset: number,
/**
* The length of the modification. Must not be negative. Empty length represents an *insert*.
*/
length: number,
/**
* The new content. Empty content represents a *remove*.
*/
content: string,
};
/**
* A text range in the document
*/
export type Range = {
/**
* The start offset of the range.
*/
offset: number,
/**
* The length of the range. Must not be negative.
*/
length: number,
};
/**
* Options used by {@linkcode format} when computing the formatting edit operations
*/
export type FormattingOptions = $ReadOnly<{
/**
* If indentation is based on spaces (`insertSpaces` = true), the number of spaces that make an indent.
*/
tabSize?: number,
/**
* Is indentation based on spaces?
*/
insertSpaces?: boolean,
/**
* The default 'end of line' character. If not set, '\n' is used as default.
*/
eol?: string,
}>;
/**
* Computes the edit operations needed to format a JSON document.
*
* @param documentText The input text
* @param range The range to format or `undefined` to format the full content
* @param options The formatting options
* @returns The edit operations describing the formatting changes to the original document following the format described in {@linkcode EditResult}.
* To apply the edit operations to the input, use {@linkcode applyEdits}.
*/
declare export function format(
documentText: string,
range: Range | void,
options: FormattingOptions,
): EditResult;
/**
* Options used by {@linkcode modify} when computing the modification edit operations
*/
export type ModificationOptions = {
/**
* Formatting options.
*/
formattingOptions: FormattingOptions,
/**
* Optional function to define the insertion index given an existing list of properties.
*/
getInsertionIndex?: (properties: string[]) => number,
};
/**
* Computes the edit operations needed to modify a value in the JSON document.
*
* @param documentText The input text
* @param path The path of the value to change. The path represents either to the document root, a property or an array item.
* If the path points to an non-existing property or item, it will be created.
* @param value The new value for the specified property or item. If the value is undefined,
* the property or item will be removed.
* @param options Options
* @returns The edit operations describing the changes to the original document, following the format described in {@linkcode EditResult}.
* To apply the edit operations to the input, use {@linkcode applyEdits}.
*/
declare export function modify(
text: string,
path: JSONPath,
value: any,
options: ModificationOptions,
): EditResult;
/**
* Applies edits to an input string.
* @param text The input text
* @param edits Edit operations following the format described in {@linkcode EditResult}.
* @returns The text with the applied edits.
* @throws An error if the edit operations are not well-formed as described in {@linkcode EditResult}.
*/
declare export function applyEdits(text: string, edits: EditResult): string;
}
-3
View File
@@ -12,6 +12,3 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# Controls whether to use Hermes from nightly builds. This will speed up builds
# but should NOT be turned on for CI or release builds.
react.internal.useHermesNightly=false
# Controls whether to use Hermes 1.0. Clean and rebuild when changing.
hermesV1Enabled=false
+3 -8
View File
@@ -54,16 +54,13 @@
"@babel/preset-env": "^7.25.3",
"@babel/preset-flow": "^7.24.7",
"@electron/packager": "^18.3.6",
"@expo/spawn-async": "^1.7.2",
"@jest/create-cache-key-function": "^29.7.0",
"@microsoft/api-extractor": "^7.52.2",
"@octokit/rest": "^22.0.0",
"@react-native/metro-babel-transformer": "0.82.0-main",
"@react-native/metro-config": "0.82.0-main",
"@tsconfig/node22": "22.0.2",
"@types/react": "^19.1.0",
"@typescript-eslint/parser": "^8.36.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.2.1",
"babel-plugin-minify-dead-code-elimination": "^0.5.2",
"babel-plugin-syntax-hermes-parser": "0.32.0",
@@ -84,9 +81,8 @@
"eslint-plugin-react-native": "^4.0.0",
"eslint-plugin-redundant-undefined": "^0.4.0",
"eslint-plugin-relay": "^1.8.3",
"fb-dotslash": "0.5.8",
"flow-api-translator": "0.32.0",
"flow-bin": "^0.281.0",
"flow-bin": "^0.280.0",
"glob": "^7.1.1",
"hermes-eslint": "0.32.0",
"hermes-transform": "0.32.0",
@@ -97,10 +93,9 @@
"jest-diff": "^29.7.0",
"jest-junit": "^16.0.0",
"jest-snapshot": "^29.7.0",
"jsonc-parser": "2.2.1",
"markdownlint-cli2": "^0.17.2",
"markdownlint-rule-relative-links": "^3.0.0",
"memfs": "^4.38.2",
"memfs": "^4.7.7",
"metro-babel-register": "^0.83.1",
"metro-transform-plugins": "^0.83.1",
"micromatch": "^4.0.4",
@@ -112,7 +107,7 @@
"react-test-renderer": "19.1.1",
"rimraf": "^3.0.2",
"shelljs": "^0.8.5",
"signedsource": "^2.0.0",
"signedsource": "^1.0.0",
"supports-color": "^7.1.0",
"temp-dir": "^2.0.0",
"tinybench": "^4.1.0",
@@ -152,7 +152,11 @@ function getShellBinaryAndArgs(
): [string, Array<string>] {
switch (flavor) {
case 'prebuilt':
return [require('fb-dotslash'), [DEVTOOLS_BINARY_DOTSLASH_FILE]];
return [
// $FlowFixMe[cannot-resolve-module] fb-dotslash includes Flow types but Flow does not pick them up
require('fb-dotslash'),
[DEVTOOLS_BINARY_DOTSLASH_FILE],
];
case 'dev':
return [
// NOTE: Internally at Meta, this is aliased to a workspace that is
@@ -44,11 +44,11 @@ async function spawnAndGetStderr(
async function prepareDebuggerShellFromDotSlashFile(
filePath: string,
): Promise<DebuggerShellPreparationResult> {
const {code, stderr} = await spawnAndGetStderr(require('fb-dotslash'), [
'--',
'fetch',
filePath,
]);
const {code, stderr} = await spawnAndGetStderr(
// $FlowFixMe[cannot-resolve-module] fb-dotslash includes Flow types but Flow does not pick them up
require('fb-dotslash'),
['--', 'fetch', filePath],
);
if (code === 0) {
return {code: 'success'};
}
+2 -2
View File
@@ -8,6 +8,8 @@
* @format
*/
export {default as createDevMiddleware} from './createDevMiddleware';
export type {
BrowserLauncher,
DebuggerShellPreparationResult,
@@ -18,7 +20,5 @@ export type {
CustomMessageHandlerConnection,
CreateCustomMessageHandlerFn,
} from './inspector-proxy/CustomMessageHandler';
export type {Logger} from './types/Logger';
export {default as unstable_DefaultBrowserLauncher} from './utils/DefaultBrowserLauncher';
export {default as createDevMiddleware} from './createDevMiddleware';
@@ -28,7 +28,6 @@ import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import com.facebook.react.utils.JdkConfiguratorUtils.configureJavaToolChains
import com.facebook.react.utils.JsonUtils
import com.facebook.react.utils.NdkConfiguratorUtils.configureReactNativeNdk
import com.facebook.react.utils.ProjectUtils.isHermesV1Enabled
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
import com.facebook.react.utils.findPackageJsonFile
import java.io.File
@@ -55,10 +54,6 @@ class ReactPlugin : Plugin<Project> {
project,
)
if (project.rootProject.isHermesV1Enabled != rootExtension.hermesV1Enabled.get()) {
rootExtension.hermesV1Enabled.set(project.rootProject.isHermesV1Enabled)
}
// App Only Configuration
project.pluginManager.withPlugin("com.android.application") {
// We wire the root extension with the values coming from the app (either user populated or
@@ -72,11 +67,9 @@ class ReactPlugin : Plugin<Project> {
val reactNativeDir = extension.reactNativeDir.get().asFile
val propertiesFile = File(reactNativeDir, "ReactAndroid/gradle.properties")
val versionAndGroupStrings = readVersionAndGroupStrings(propertiesFile)
val hermesV1Enabled =
if (project.rootProject.hasProperty("hermesV1Enabled"))
project.rootProject.findProperty("hermesV1Enabled") == "true"
else false
configureDependencies(project, versionAndGroupStrings, hermesV1Enabled)
val versionString = versionAndGroupStrings.first
val groupString = versionAndGroupStrings.second
configureDependencies(project, versionString, groupString)
configureRepositories(project)
}
@@ -11,7 +11,6 @@ import javax.inject.Inject
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
/**
* A private extension we set on the rootProject to make easier to share values at execution time
@@ -58,6 +57,4 @@ abstract class PrivateReactExtension @Inject constructor(project: Project) {
val codegenDir: DirectoryProperty =
objects.directoryProperty().convention(root.dir("node_modules/@react-native/codegen"))
val hermesV1Enabled: Property<Boolean> = objects.property(Boolean::class.java).convention(false)
}
@@ -94,12 +94,7 @@ abstract class BundleHermesCTask : DefaultTask() {
runCommand(bundleCommand)
if (hermesEnabled.get()) {
val hermesV1Enabled =
if (project.rootProject.hasProperty("hermesV1Enabled"))
project.rootProject.findProperty("hermesV1Enabled") == "true"
else false
val detectedHermesCommand =
detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get(), hermesV1Enabled)
val detectedHermesCommand = detectOSAwareHermesCommand(root.get().asFile, hermesCommand.get())
val bytecodeFile = File("${bundleFile}.hbc")
val outputSourceMap = resolveOutputSourceMap(bundleAssetFilename)
val compilerSourceMap = resolveCompilerSourceMap(bundleAssetFilename)
@@ -7,15 +7,12 @@
package com.facebook.react.utils
import com.facebook.react.utils.PropertyUtils.DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.DEFAULT_INTERNAL_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.EXCLUSIVE_ENTEPRISE_REPOSITORY
import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY
import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY_DEFAULT
import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.INTERNAL_HERMES_VERSION_NAME
import com.facebook.react.utils.PropertyUtils.INTERNAL_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO
import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.INTERNAL_USE_HERMES_NIGHTLY
import com.facebook.react.utils.PropertyUtils.INTERNAL_VERSION_NAME
import com.facebook.react.utils.PropertyUtils.SCOPED_EXCLUSIVE_ENTEPRISE_REPOSITORY
@@ -28,13 +25,6 @@ import org.gradle.api.artifacts.repositories.MavenArtifactRepository
internal object DependencyUtils {
internal data class Coordinates(
val versionString: String,
val hermesVersionString: String,
val reactGroupString: String = DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP,
val hermesGroupString: String = DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP,
)
/**
* This method takes care of configuring the repositories{} block for both the app and all the 3rd
* party libraries which are auto-linked.
@@ -105,15 +95,14 @@ internal object DependencyUtils {
* This method takes care of configuring the resolution strategy for both the app and all the 3rd
* party libraries which are auto-linked. Specifically it takes care of:
* - Forcing the react-android/hermes-android version to the one specified in the package.json
* - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`
* - Selecting between the classic Hermes and Hermes V1
* - Substituting `react-native` with `react-android` and `hermes-engine` with `hermes-android`.
*/
fun configureDependencies(
project: Project,
coordinates: Coordinates,
hermesV1Enabled: Boolean = false,
versionString: String,
groupString: String = DEFAULT_INTERNAL_PUBLISHING_GROUP,
) {
if (coordinates.versionString.isBlank() || coordinates.hermesVersionString.isBlank()) return
if (versionString.isBlank()) return
project.rootProject.allprojects { eachProject ->
eachProject.configurations.all { configuration ->
// Here we set a dependencySubstitution for both react-native and hermes-engine as those
@@ -121,61 +110,53 @@ internal object DependencyUtils {
// This allows users to import libraries that are still using
// implementation("com.facebook.react:react-native:+") and resolve the right dependency.
configuration.resolutionStrategy.dependencySubstitution {
getDependencySubstitutions(coordinates, hermesV1Enabled).forEach { (module, dest, reason)
->
getDependencySubstitutions(versionString, groupString).forEach { (module, dest, reason) ->
it.substitute(it.module(module)).using(it.module(dest)).because(reason)
}
}
configuration.resolutionStrategy.force(
"${coordinates.reactGroupString}:react-android:${coordinates.versionString}",
"${groupString}:react-android:${versionString}",
)
if (!(eachProject.findProperty(INTERNAL_USE_HERMES_NIGHTLY) as? String).toBoolean()) {
// Contributors only: The hermes-engine version is forced only if the user has
// not opted into using nightlies for local development.
configuration.resolutionStrategy.force(
"${coordinates.reactGroupString}:hermes-android:${coordinates.versionString}"
)
configuration.resolutionStrategy.force("${groupString}:hermes-android:${versionString}")
}
}
}
}
internal fun getDependencySubstitutions(
coordinates: Coordinates,
hermesV1Enabled: Boolean = false,
versionString: String,
groupString: String = DEFAULT_INTERNAL_PUBLISHING_GROUP,
): List<Triple<String, String, String>> {
// TODO: T231755027 update coordinates and versioning
val dependencySubstitution = mutableListOf<Triple<String, String, String>>()
val hermesVersionString =
if (hermesV1Enabled)
"${coordinates.hermesGroupString}:hermes-android:${coordinates.versionString}"
else "${coordinates.reactGroupString}:hermes-android:${coordinates.versionString}"
dependencySubstitution.add(
Triple(
"com.facebook.react:react-native",
"${coordinates.reactGroupString}:react-android:${coordinates.versionString}",
"${groupString}:react-android:${versionString}",
"The react-native artifact was deprecated in favor of react-android due to https://github.com/facebook/react-native/issues/35210.",
)
)
dependencySubstitution.add(
Triple(
"com.facebook.react:hermes-engine",
hermesVersionString,
"${groupString}:hermes-android:${versionString}",
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210.",
)
)
if (coordinates.reactGroupString != DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP) {
if (groupString != DEFAULT_INTERNAL_PUBLISHING_GROUP) {
dependencySubstitution.add(
Triple(
"com.facebook.react:react-android",
"${coordinates.reactGroupString}:react-android:${coordinates.versionString}",
"${groupString}:react-android:${versionString}",
"The react-android dependency was modified to use the correct Maven group.",
)
)
dependencySubstitution.add(
Triple(
"com.facebook.react:hermes-android",
hermesVersionString,
"${groupString}:hermes-android:${versionString}",
"The hermes-android dependency was modified to use the correct Maven group.",
)
)
@@ -183,14 +164,10 @@ internal object DependencyUtils {
return dependencySubstitution
}
fun readVersionAndGroupStrings(propertiesFile: File): Coordinates {
fun readVersionAndGroupStrings(propertiesFile: File): Pair<String, String> {
val reactAndroidProperties = Properties()
propertiesFile.inputStream().use { reactAndroidProperties.load(it) }
val versionStringFromFile = (reactAndroidProperties[INTERNAL_VERSION_NAME] as? String).orEmpty()
// TODO: T231755027 update HERMES_VERSION_NAME in gradle.properties to point to the correct
// hermes version
val hermesVersionStringFromFile =
(reactAndroidProperties[INTERNAL_HERMES_VERSION_NAME] as? String).orEmpty()
// If on a nightly, we need to fetch the -SNAPSHOT artifact from Sonatype.
val versionString =
if (versionStringFromFile.startsWith("0.0.0") || "-nightly-" in versionStringFromFile) {
@@ -199,18 +176,10 @@ internal object DependencyUtils {
versionStringFromFile
}
// Returns Maven group for repos using different group for Maven artifacts
val reactGroupString =
reactAndroidProperties[INTERNAL_REACT_PUBLISHING_GROUP] as? String
?: DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP
val hermesGroupString =
reactAndroidProperties[INTERNAL_HERMES_PUBLISHING_GROUP] as? String
?: DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP
return Coordinates(
versionString,
hermesVersionStringFromFile,
reactGroupString,
hermesGroupString,
)
val groupString =
reactAndroidProperties[INTERNAL_PUBLISHING_GROUP] as? String
?: DEFAULT_INTERNAL_PUBLISHING_GROUP
return Pair(versionString, groupString)
}
fun Project.mavenRepoFromUrl(
@@ -122,16 +122,11 @@ private fun detectCliFile(reactNativeRoot: File, preconfiguredCliFile: File?): F
* used if the user is building Hermes from source.
* 3. The file located in `node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc` where `%OS-BIN%`
* is substituted with the correct OS arch. This will be used if the user is using a precompiled
* hermes-engine package. Or, if the user has opted in to use Hermes V1, the used file will be
* located in `node_modules/hermes-compiler/%OS-BIN%/hermesc` where `%OS-BIN%` is substituted
* with the correct OS arch.
* hermes-engine package.
* 4. Fails otherwise
*/
internal fun detectOSAwareHermesCommand(
projectRoot: File,
hermesCommand: String,
hermesV1Enabled: Boolean = false,
): String { // 1. If the project specifies a Hermes command, don't second guess it.
internal fun detectOSAwareHermesCommand(projectRoot: File, hermesCommand: String): String {
// 1. If the project specifies a Hermes command, don't second guess it.
if (hermesCommand.isNotBlank()) {
val osSpecificHermesCommand =
if ("%OS-BIN%" in hermesCommand) {
@@ -151,12 +146,9 @@ internal fun detectOSAwareHermesCommand(
return builtHermesc.cliPath(projectRoot)
}
// 3. If Hermes V1 is enabled, use hermes-compiler from npm, otherwise, if the
// react-native contains a pre-built hermesc, use it.
val hermesCPath = if (hermesV1Enabled) HERMES_COMPILER_NPM_DIR else HERMESC_IN_REACT_NATIVE_DIR
// 3. If the react-native contains a pre-built hermesc, use it.
val prebuiltHermesPath =
hermesCPath
.plus(getHermesCBin())
HERMESC_IN_REACT_NATIVE_DIR.plus(getHermesCBin())
.replace("%OS-BIN%", getHermesOSBin())
// Execution on Windows fails with / as separator
.replace('/', File.separatorChar)
@@ -241,7 +233,6 @@ internal fun readPackageJsonFile(
return packageJson?.let { JsonUtils.fromPackageJson(it) }
}
private const val HERMES_COMPILER_NPM_DIR = "node_modules/hermes-compiler/%OS-BIN%/"
private const val HERMESC_IN_REACT_NATIVE_DIR = "node_modules/react-native/sdks/hermesc/%OS-BIN%/"
private const val HERMESC_BUILT_FROM_SOURCE_DIR =
"node_modules/react-native/ReactAndroid/hermes-engine/build/hermes/bin/"
@@ -13,11 +13,9 @@ import com.facebook.react.utils.KotlinStdlibCompatUtils.lowercaseCompat
import com.facebook.react.utils.KotlinStdlibCompatUtils.toBooleanStrictOrNullCompat
import com.facebook.react.utils.PropertyUtils.EDGE_TO_EDGE_ENABLED
import com.facebook.react.utils.PropertyUtils.HERMES_ENABLED
import com.facebook.react.utils.PropertyUtils.HERMES_V1_ENABLED
import com.facebook.react.utils.PropertyUtils.REACT_NATIVE_ARCHITECTURES
import com.facebook.react.utils.PropertyUtils.SCOPED_EDGE_TO_EDGE_ENABLED
import com.facebook.react.utils.PropertyUtils.SCOPED_HERMES_ENABLED
import com.facebook.react.utils.PropertyUtils.SCOPED_HERMES_V1_ENABLED
import com.facebook.react.utils.PropertyUtils.SCOPED_REACT_NATIVE_ARCHITECTURES
import com.facebook.react.utils.PropertyUtils.SCOPED_USE_THIRD_PARTY_JSC
import com.facebook.react.utils.PropertyUtils.USE_THIRD_PARTY_JSC
@@ -70,13 +68,6 @@ internal object ProjectUtils {
(project.hasProperty(SCOPED_USE_THIRD_PARTY_JSC) &&
project.property(SCOPED_USE_THIRD_PARTY_JSC).toString().toBoolean())
internal val Project.isHermesV1Enabled: Boolean
get() =
(project.hasProperty(HERMES_V1_ENABLED) &&
project.property(HERMES_V1_ENABLED).toString().toBoolean()) ||
(project.hasProperty(SCOPED_HERMES_V1_ENABLED) &&
project.property(SCOPED_HERMES_V1_ENABLED).toString().toBoolean())
internal fun Project.needsCodegenFromPackageJson(rootProperty: DirectoryProperty): Boolean {
val parsedPackageJson = readPackageJsonFile(this, rootProperty)
return needsCodegenFromPackageJson(parsedPackageJson)
@@ -18,10 +18,6 @@ object PropertyUtils {
const val HERMES_ENABLED = "hermesEnabled"
const val SCOPED_HERMES_ENABLED = "react.hermesEnabled"
/** Public property that toggles Hermes V1 */
const val HERMES_V1_ENABLED = "hermesV1Enabled"
const val SCOPED_HERMES_V1_ENABLED = "react.hermesV1Enabled"
/** Public property that toggles edge-to-edge */
const val EDGE_TO_EDGE_ENABLED = "edgeToEdgeEnabled"
const val SCOPED_EDGE_TO_EDGE_ENABLED = "react.edgeToEdgeEnabled"
@@ -72,13 +68,9 @@ object PropertyUtils {
const val INTERNAL_USE_HERMES_NIGHTLY = "react.internal.useHermesNightly"
/** Internal property used to override the publishing group for the React Native artifacts. */
const val INTERNAL_REACT_PUBLISHING_GROUP = "react.internal.publishingGroup"
const val INTERNAL_HERMES_PUBLISHING_GROUP = "react.internal.hermesPublishingGroup"
const val DEFAULT_INTERNAL_REACT_PUBLISHING_GROUP = "com.facebook.react"
const val DEFAULT_INTERNAL_HERMES_PUBLISHING_GROUP = "com.facebook.hermes"
const val INTERNAL_PUBLISHING_GROUP = "react.internal.publishingGroup"
const val DEFAULT_INTERNAL_PUBLISHING_GROUP = "com.facebook.react"
/** Internal property used to control the version name of React Native */
const val INTERNAL_VERSION_NAME = "VERSION_NAME"
/** Internal property used to control the version name of Hermes Engine */
const val INTERNAL_HERMES_VERSION_NAME = "HERMES_VERSION_NAME"
}
@@ -34,9 +34,9 @@ class GenerateAutolinkingNewArchitecturesFileTaskTest {
val inputFile = tempFolder.newFile("config.json")
val task =
createTestTask<GenerateAutolinkingNewArchitecturesFileTask> { task ->
task.generatedOutputDirectory.set(outputFolder)
task.autolinkInputFile.set(inputFile)
createTestTask<GenerateAutolinkingNewArchitecturesFileTask> {
it.generatedOutputDirectory.set(outputFolder)
it.autolinkInputFile.set(inputFile)
}
assertThat(task.generatedOutputDirectory.get().asFile).isEqualTo(outputFolder)
@@ -271,13 +271,11 @@ class DependencyUtilsTest {
.isEqualTo(2)
}
// TODO: T236767053
@Test
fun configureDependencies_withEmptyVersion_doesNothing() {
val project = createProject()
configureDependencies(project, DependencyUtils.Coordinates("", ""))
configureDependencies(project, "")
assertThat(project.configurations.first().resolutionStrategy.forcedModules.isEmpty()).isTrue()
}
@@ -286,7 +284,7 @@ class DependencyUtilsTest {
fun configureDependencies_withVersionString_appliesResolutionStrategy() {
val project = createProject()
configureDependencies(project, DependencyUtils.Coordinates("1.2.3", "1.2.3"))
configureDependencies(project, "1.2.3")
val forcedModules = project.configurations.first().resolutionStrategy.forcedModules
assertThat(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
@@ -303,7 +301,7 @@ class DependencyUtilsTest {
appProject.plugins.apply("com.android.application")
libProject.plugins.apply("com.android.library")
configureDependencies(appProject, DependencyUtils.Coordinates("1.2.3", "1.2.3"))
configureDependencies(appProject, "1.2.3")
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
@@ -325,10 +323,7 @@ class DependencyUtilsTest {
appProject.plugins.apply("com.android.application")
libProject.plugins.apply("com.android.library")
configureDependencies(
appProject,
DependencyUtils.Coordinates("1.2.3", "1.2.3", "io.github.test"),
)
configureDependencies(appProject, "1.2.3", "io.github.test")
val appForcedModules = appProject.configurations.first().resolutionStrategy.forcedModules
val libForcedModules = libProject.configurations.first().resolutionStrategy.forcedModules
@@ -344,8 +339,7 @@ class DependencyUtilsTest {
@Test
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly() {
val dependencySubstitutions =
getDependencySubstitutions(DependencyUtils.Coordinates("0.42.0", "0.42.0"))
val dependencySubstitutions = getDependencySubstitutions("0.42.0")
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
assertThat("com.facebook.react:react-android:0.42.0")
@@ -365,10 +359,7 @@ class DependencyUtilsTest {
@Test
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly() {
val dependencySubstitutions =
getDependencySubstitutions(
DependencyUtils.Coordinates("0.42.0", "0.42.0", "io.github.test")
)
val dependencySubstitutions = getDependencySubstitutions("0.42.0", "io.github.test")
assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
assertThat("io.github.test:react-android:0.42.0").isEqualTo(dependencySubstitutions[0].second)
@@ -405,7 +396,7 @@ class DependencyUtilsTest {
)
}
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertThat(versionString).isEqualTo("1000.0.0")
}
@@ -423,7 +414,7 @@ class DependencyUtilsTest {
)
}
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertThat(versionString).isEqualTo("0.0.0-20221101-2019-cfe811ab1-SNAPSHOT")
}
@@ -440,7 +431,7 @@ class DependencyUtilsTest {
)
}
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertThat(versionString).isEqualTo("")
}
@@ -457,7 +448,7 @@ class DependencyUtilsTest {
)
}
val versionString = readVersionAndGroupStrings(propertiesFile).versionString
val versionString = readVersionAndGroupStrings(propertiesFile).first
assertThat(versionString).isEqualTo("")
}
@@ -474,7 +465,7 @@ class DependencyUtilsTest {
)
}
val groupString = readVersionAndGroupStrings(propertiesFile).reactGroupString
val groupString = readVersionAndGroupStrings(propertiesFile).second
assertThat(groupString).isEqualTo("io.github.test")
}
@@ -491,7 +482,7 @@ class DependencyUtilsTest {
)
}
val groupString = readVersionAndGroupStrings(propertiesFile).reactGroupString
val groupString = readVersionAndGroupStrings(propertiesFile).second
assertThat(groupString).isEqualTo("com.facebook.react")
}
@@ -162,16 +162,6 @@ class PathUtilsTest {
assertThat(detectOSAwareHermesCommand(tempFolder.root, "")).isEqualTo(expected.toString())
}
@Test
@WithOs(OS.MAC)
fun detectOSAwareHermesCommand_withHermesV1Enabled() {
tempFolder.newFolder("node_modules/hermes-compiler/osx-bin/")
val expected = tempFolder.newFile("node_modules/hermes-compiler/osx-bin//hermesc")
assertThat(detectOSAwareHermesCommand(tempFolder.root, "", hermesV1Enabled = true))
.isEqualTo(expected.toString())
}
@Test(expected = IllegalStateException::class)
@WithOs(OS.MAC)
fun detectOSAwareHermesCommand_failsIfNotFound() {
@@ -14,7 +14,6 @@ import com.facebook.react.tests.createProject
import com.facebook.react.utils.ProjectUtils.getReactNativeArchitectures
import com.facebook.react.utils.ProjectUtils.isEdgeToEdgeEnabled
import com.facebook.react.utils.ProjectUtils.isHermesEnabled
import com.facebook.react.utils.ProjectUtils.isHermesV1Enabled
import com.facebook.react.utils.ProjectUtils.isNewArchEnabled
import com.facebook.react.utils.ProjectUtils.needsCodegenFromPackageJson
import java.io.File
@@ -116,32 +115,6 @@ class ProjectUtilsTest {
assertThat(project.isEdgeToEdgeEnabled).isFalse()
}
@Test
fun isHermesV1Enabled_returnsFalseByDefault() {
assertThat(createProject().isHermesV1Enabled).isFalse()
}
@Test
fun isHermesV1Enabled_withDisabledViaProperty_returnsFalse() {
val project = createProject()
project.extensions.extraProperties.set("hermesV1Enabled", "false")
assertThat(project.isHermesV1Enabled).isFalse()
}
@Test
fun isHermesV1Enabled_withEnabledViaProperty_returnsTrue() {
val project = createProject()
project.extensions.extraProperties.set("hermesV1Enabled", "true")
assertThat(project.isHermesV1Enabled).isTrue()
}
@Test
fun isHermesV1Enabled_withInvalidViaProperty_returnsFalse() {
val project = createProject()
project.extensions.extraProperties.set("hermesV1Enabled", "¯\\_(ツ)_/¯")
assertThat(project.isHermesV1Enabled).isFalse()
}
@Test
fun needsCodegenFromPackageJson_withCodegenConfigInPackageJson_returnsTrue() {
val project = createProject()
@@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTBridgeDelegate.h>
#import <React/RCTConvert.h>
#import <UIKit/UIKit.h>
#import "RCTDefaultReactNativeFactoryDelegate.h"
#import "RCTReactNativeFactory.h"
@@ -6,7 +6,6 @@
*/
#import "RCTAppDelegate.h"
#import <React/RCTBridgeDelegate.h>
#import <React/RCTLog.h>
#import <React/RCTRootView.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
@@ -54,7 +54,7 @@ RCTAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary
NSArray<NSString *> *RCTAppSetupUnstableModulesRequiringMainQueueSetup(id<RCTDependencyProvider> dependencyProvider)
{
// For oss, insert core main queue setup modules here
return (dependencyProvider != nullptr) ? dependencyProvider.unstableModulesRequiringMainQueueSetup : @[];
return dependencyProvider ? dependencyProvider.unstableModulesRequiringMainQueueSetup : @[];
}
id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass, id<RCTDependencyProvider> dependencyProvider)
@@ -65,11 +65,11 @@ id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass, id<RCTDe
NSArray<NSString *> *classNames = @[];
if (protocol == @protocol(RCTImageURLLoader)) {
classNames = (dependencyProvider != nullptr) ? dependencyProvider.imageURLLoaderClassNames : @[];
classNames = dependencyProvider ? dependencyProvider.imageURLLoaderClassNames : @[];
} else if (protocol == @protocol(RCTImageDataDecoder)) {
classNames = (dependencyProvider != nullptr) ? dependencyProvider.imageDataDecoderClassNames : @[];
classNames = dependencyProvider ? dependencyProvider.imageDataDecoderClassNames : @[];
} else if (protocol == @protocol(RCTURLRequestHandler)) {
classNames = (dependencyProvider != nullptr) ? dependencyProvider.URLRequestHandlerClassNames : @[];
classNames = dependencyProvider ? dependencyProvider.URLRequestHandlerClassNames : @[];
}
NSMutableArray *modules = [NSMutableArray new];
@@ -78,7 +78,7 @@
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
return (self.dependencyProvider != nullptr) ? self.dependencyProvider.thirdPartyFabricComponents : @{};
return self.dependencyProvider ? self.dependencyProvider.thirdPartyFabricComponents : @{};
}
- (void)hostDidStart:(RCTHost *)host
@@ -87,15 +87,13 @@
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup
{
return (self.dependencyProvider != nullptr)
? RCTAppSetupUnstableModulesRequiringMainQueueSetup(self.dependencyProvider)
: @[];
return self.dependencyProvider ? RCTAppSetupUnstableModulesRequiringMainQueueSetup(self.dependencyProvider) : @[];
}
- (nullable id<RCTModuleProvider>)getModuleProvider:(const char *)name
{
NSString *providerName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
return (self.dependencyProvider != nullptr) ? self.dependencyProvider.moduleProviders[providerName] : nullptr;
return self.dependencyProvider ? self.dependencyProvider.moduleProviders[providerName] : nullptr;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
@@ -6,7 +6,6 @@
*
* @flow strict
* @format
* @deprecated
*/
'use strict';
@@ -6,7 +6,6 @@
*
* @flow strict
* @format
* @deprecated
*/
'use strict';
@@ -31,7 +31,7 @@ void RCTBlobCollector::install(RCTBlobManager *blobManager)
__weak RCTCxxBridge *cxxBridge = (RCTCxxBridge *)blobManager.bridge;
[cxxBridge
dispatchBlock:^{
if ((cxxBridge == nullptr) || cxxBridge.runtime == nullptr) {
if (!cxxBridge || cxxBridge.runtime == nullptr) {
return;
}
jsi::Runtime &runtime = *(jsi::Runtime *)cxxBridge.runtime;
@@ -6,7 +6,6 @@
*
* @flow
* @format
* @deprecated
*/
import NativeTiming from './NativeTiming';
@@ -6,7 +6,6 @@
*
* @flow strict
* @format
* @deprecated
*/
export * from '../../../src/private/specs_DEPRECATED/modules/NativeTiming';
@@ -6,7 +6,6 @@
*
* @flow
* @format
* @deprecated
*/
'use strict';
@@ -50,8 +50,8 @@ RCT_EXPORT_MODULE()
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
UIImage *image = RCTImageFromLocalAssetURL(imageURL);
if (image != nullptr) {
if (progressHandler != nullptr) {
if (image) {
if (progressHandler) {
progressHandler(1, 1);
}
completionHandler(nil, image);
@@ -27,7 +27,7 @@ RCT_EXPORT_MODULE()
char header[7] = {};
[imageData getBytes:header length:6];
return (strcmp(header, "GIF87a") == 0) || (strcmp(header, "GIF89a") == 0);
return !strcmp(header, "GIF87a") || !strcmp(header, "GIF89a");
}
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData
@@ -38,7 +38,7 @@ RCT_EXPORT_MODULE()
{
RCTAnimatedImage *image = [[RCTAnimatedImage alloc] initWithData:imageData scale:scale];
if (image == nullptr) {
if (!image) {
completionHandler(nil, nil);
return ^{
};
@@ -19,7 +19,7 @@ UIImage *RCTBlurredImageWithRadius(UIImage *inputImage, CGFloat radius)
}
// convert to ARGB if it isn't
if (CGImageGetBitsPerPixel(imageRef) != 32 || (((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask)) == 0u)) {
if (CGImageGetBitsPerPixel(imageRef) != 32 || !((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask))) {
UIGraphicsImageRendererFormat *const rendererFormat = [UIGraphicsImageRendererFormat defaultFormat];
rendererFormat.scale = inputImage.scale;
UIGraphicsImageRenderer *const renderer = [[UIGraphicsImageRenderer alloc] initWithSize:inputImage.size
@@ -36,11 +36,11 @@ UIImage *RCTBlurredImageWithRadius(UIImage *inputImage, CGFloat radius)
buffer1.rowBytes = buffer2.rowBytes = CGImageGetBytesPerRow(imageRef);
size_t bytes = buffer1.rowBytes * buffer1.height;
buffer1.data = malloc(bytes);
if (buffer1.data == nullptr) {
if (!buffer1.data) {
return inputImage;
}
buffer2.data = malloc(bytes);
if (buffer2.data == nullptr) {
if (!buffer2.data) {
free(buffer1.data);
return inputImage;
}
@@ -60,7 +60,7 @@ UIImage *RCTBlurredImageWithRadius(UIImage *inputImage, CGFloat radius)
return inputImage;
}
void *tempBuffer = malloc(tempBufferSize);
if (tempBuffer == nullptr) {
if (!tempBuffer) {
free(buffer1.data);
free(buffer2.data);
return inputImage;
@@ -48,7 +48,7 @@ RCT_EXPORT_MODULE()
{
dispatch_async(_methodQueue, ^{
[self removeImageForTag:imageTag];
if (block != nullptr) {
if (block) {
block();
}
});
@@ -58,7 +58,7 @@ RCT_EXPORT_MODULE()
{
RCTAssertThread(_methodQueue, @"Must be called on RCTImageStoreManager thread");
if (_store == nullptr) {
if (!_store) {
_store = [NSMutableDictionary new];
_id = 0;
}
@@ -112,7 +112,7 @@ RCT_EXPORT_METHOD(getBase64ForTag
: (RCTResponseSenderBlock)errorCallback)
{
NSData *imageData = _store[imageTag];
if (imageData == nullptr) {
if (!imageData) {
errorCallback(
@[ RCTJSErrorFromNSError(RCTErrorWithMessage([NSString stringWithFormat:@"Invalid imageTag: %@", imageTag])) ]);
return;
@@ -132,7 +132,7 @@ RCT_EXPORT_METHOD(addImageFromBase64
// Dispatching to a background thread to perform base64 decoding
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
if (imageData != nullptr) {
if (imageData) {
dispatch_async(self->_methodQueue, ^{
successCallback(@[ [self _storeImageData:imageData] ]);
});
@@ -164,14 +164,14 @@ RCT_EXPORT_METHOD(addImageFromBase64
NSString *imageTag = request.URL.absoluteString;
NSData *imageData = self->_store[imageTag];
if (imageData == nullptr) {
if (!imageData) {
NSError *error = RCTErrorWithMessage([NSString stringWithFormat:@"Invalid imageTag: %@", imageTag]);
[delegate URLRequest:cancellationBlock didCompleteWithError:error];
return;
}
CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
if (sourceRef == nullptr) {
if (!sourceRef) {
NSError *error =
RCTErrorWithMessage([NSString stringWithFormat:@"Unable to decode data for imageTag: %@", imageTag]);
[delegate URLRequest:cancellationBlock didCompleteWithError:error];
@@ -197,7 +197,7 @@ RCT_EXPORT_METHOD(addImageFromBase64
- (void)cancelRequest:(id)requestToken
{
if (requestToken != nullptr) {
if (requestToken) {
((void (^)(void))requestToken)();
}
}
@@ -50,8 +50,8 @@ RCT_EXPORT_MODULE()
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
UIImage *image = RCTImageFromLocalAssetURL(imageURL);
if (image != nullptr) {
if (progressHandler != nullptr) {
if (image) {
if (progressHandler) {
progressHandler(1, 1);
}
completionHandler(nil, image);
@@ -155,7 +155,7 @@ RCT_EXPORT_METHOD(canOpenURL
RCT_EXPORT_METHOD(getInitialURL : (RCTPromiseResolveBlock)resolve reject : (__unused RCTPromiseRejectBlock)reject)
{
NSURL *initialURL = nil;
if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey] != nullptr) {
if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) {
initialURL = self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey];
} else {
NSDictionary *userActivityDictionary =
@@ -13,7 +13,7 @@
- (instancetype)initWithEventPath:(NSArray<NSString *> *)eventPath valueNode:(RCTValueAnimatedNode *)valueNode
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_eventPath = eventPath;
_valueNode = valueNode;
}
@@ -16,7 +16,7 @@
- (instancetype)initWithTag:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_nodeTag = tag;
_config = [config copy];
}
@@ -37,10 +37,10 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (void)addChild:(RCTAnimatedNode *)child
{
if (_childNodes == nullptr) {
if (!_childNodes) {
_childNodes = [NSMapTable strongToWeakObjectsMapTable];
}
if (child != nullptr) {
if (child) {
[_childNodes setObject:child forKey:child.nodeTag];
[child onAttachedToNode:self];
}
@@ -48,10 +48,10 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (void)removeChild:(RCTAnimatedNode *)child
{
if (_childNodes == nullptr) {
if (!_childNodes) {
return;
}
if (child != nullptr) {
if (child) {
[_childNodes removeObjectForKey:child.nodeTag];
[child onDetachedFromNode:self];
}
@@ -59,20 +59,20 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (void)onAttachedToNode:(RCTAnimatedNode *)parent
{
if (_parentNodes == nullptr) {
if (!_parentNodes) {
_parentNodes = [NSMapTable strongToWeakObjectsMapTable];
}
if (parent != nullptr) {
if (parent) {
[_parentNodes setObject:parent forKey:parent.nodeTag];
}
}
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent
{
if (_parentNodes == nullptr) {
if (!_parentNodes) {
return;
}
if (parent != nullptr) {
if (parent) {
[_parentNodes removeObjectForKey:parent.nodeTag];
}
}
@@ -86,7 +86,7 @@ NSString *RCTInterpolateString(
- (instancetype)initWithTag:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config
{
if ((self = [super initWithTag:tag config:config]) != nullptr) {
if ((self = [super initWithTag:tag config:config])) {
_inputRange = config[@"inputRange"];
NSArray *outputRangeConfig = config[@"outputRange"];
@@ -104,7 +104,7 @@ NSString *RCTInterpolateString(
switch (_outputType) {
case RCTInterpolationOutputColor: {
UIColor *color = [RCTConvert UIColor:value];
[outputRange addObject:(color != nullptr) ? color : [UIColor whiteColor]];
[outputRange addObject:color ? color : [UIColor whiteColor]];
break;
}
case RCTInterpolationOutputString:
@@ -141,7 +141,7 @@ NSString *RCTInterpolateString(
- (void)performUpdate
{
[super performUpdate];
if (_parentNode == nullptr) {
if (!_parentNode) {
return;
}
@@ -48,7 +48,7 @@ NSString *const NODE_TAG_KEY = @"nodeTag";
if ([value isKindOfClass:[NSDictionary class]]) {
NSDictionary<NSString *, id> *dict = (NSDictionary *)value;
id nodeTag = [dict objectForKey:NODE_TAG_KEY];
if ((nodeTag != nullptr) && [nodeTag isKindOfClass:[NSNumber class]]) {
if (nodeTag && [nodeTag isKindOfClass:[NSNumber class]]) {
RCTAnimatedNode *node = [self.parentNodes objectForKey:(NSNumber *)nodeTag];
if ([node isKindOfClass:[RCTValueAnimatedNode class]]) {
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
@@ -18,7 +18,7 @@
- (instancetype)initWithTag:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config
{
if ((self = [super initWithTag:tag config:config]) != nullptr) {
if ((self = [super initWithTag:tag config:config])) {
_propsDictionary = [NSMutableDictionary new];
}
return self;
@@ -36,11 +36,11 @@
NSDictionary<NSString *, NSNumber *> *style = self.config[@"style"];
[style enumerateKeysAndObjectsUsingBlock:^(NSString *property, NSNumber *nodeTag, __unused BOOL *stop) {
RCTAnimatedNode *node = [self.parentNodes objectForKey:nodeTag];
if (node != nullptr) {
if (node) {
if ([node isKindOfClass:[RCTValueAnimatedNode class]]) {
RCTValueAnimatedNode *valueAnimatedNode = (RCTValueAnimatedNode *)node;
id animatedObject = valueAnimatedNode.animatedObject;
if (animatedObject != nullptr) {
if (animatedObject) {
_propsDictionary[property] = animatedObject;
} else {
_propsDictionary[property] = @(valueAnimatedNode.value);
@@ -18,7 +18,7 @@
- (instancetype)initWithTag:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config
{
if ((self = [super initWithTag:tag config:config]) != nullptr) {
if ((self = [super initWithTag:tag config:config])) {
_animationId = config[@"animationId"];
_toValueNodeTag = config[@"toValue"];
_valueNodeTag = config[@"value"];
@@ -14,7 +14,7 @@
- (instancetype)initWithTag:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config
{
if ((self = [super initWithTag:tag config:config]) != nullptr) {
if ((self = [super initWithTag:tag config:config])) {
_propsDictionary = [NSMutableDictionary new];
}
return self;
@@ -59,7 +59,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
- (instancetype)initWithBridge:(nullable RCTBridge *)bridge
surfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_bridge = bridge;
_surfacePresenter = surfacePresenter;
_animationNodes = [NSMutableDictionary new];
@@ -72,7 +72,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
- (BOOL)isNodeManagedByFabric:(NSNumber *)tag
{
RCTAnimatedNode *node = _animationNodes[tag];
if (node != nullptr) {
if (node) {
return [node isManagedByFabric];
}
return false;
@@ -106,7 +106,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
NSString *nodeType = [RCTConvert NSString:config[@"type"]];
Class nodeClass = map[nodeType];
if (nodeClass == nullptr) {
if (!nodeClass) {
RCTLogError(@"Animated node type %@ not supported natively", nodeType);
return;
}
@@ -187,7 +187,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
- (void)dropAnimatedNode:(NSNumber *)tag
{
RCTAnimatedNode *node = _animationNodes[tag];
if (node != nullptr) {
if (node) {
[node detachNode];
[_animationNodes removeObjectForKey:tag];
}
@@ -345,7 +345,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
NSNumber *nodeTag = [RCTConvert NSNumber:eventMapping[@"animatedValueTag"]];
RCTAnimatedNode *node = _animationNodes[nodeTag];
if (node == nullptr) {
if (!node) {
RCTLogError(@"Animated node with tag %@ does not exist", nodeTag);
return;
}
@@ -407,7 +407,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, RCTNormalizeAnimatedEventName(event.eventName)];
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
if (driversForKey != nullptr) {
if (driversForKey) {
for (RCTEventAnimation *driver in driversForKey) {
[self stopAnimationsForNode:driver.valueNode];
[driver updateWithEvent:event];
@@ -439,7 +439,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
- (void)startAnimationLoopIfNeeded
{
if ((_displayLink == nullptr) && _activeAnimations.count > 0) {
if (!_displayLink && _activeAnimations.count > 0) {
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(stepAnimations:)];
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
@@ -454,7 +454,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
- (void)stopAnimationLoop
{
if (_displayLink != nullptr) {
if (_displayLink) {
[_displayLink invalidate];
_displayLink = nil;
}
@@ -486,7 +486,7 @@ static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
NSArray<RCTEventAnimation *> *eventAnimations = _eventDrivers[key];
for (RCTEventAnimation *animation in eventAnimations) {
NSNumber *nodeTag = [animation.valueNode nodeTag];
if (nodeTag != nullptr) {
if (nodeTag) {
[tags addObject:nodeTag];
}
for (NSNumber *childNodeKey in [animation.valueNode childNodes]) {
@@ -25,7 +25,7 @@ RCT_EXPORT_MODULE()
- (void)invalidate
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
if (_queue != nullptr) {
if (_queue) {
for (NSOperation *operation in _queue.operations) {
if (!operation.isCancelled && !operation.isFinished) {
[operation cancel];
@@ -44,7 +44,7 @@ RCT_EXPORT_MODULE()
{
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
// Lazy setup
if (_queue == nullptr) {
if (!_queue) {
_queue = [NSOperationQueue new];
_queue.maxConcurrentOperationCount = 2;
}
@@ -59,7 +59,7 @@ RCT_EXPORT_MODULE()
// Get mime type
NSRange firstSemicolon = [request.URL.resourceSpecifier rangeOfString:@";"];
NSString *mimeType =
(firstSemicolon.length != 0u) ? [request.URL.resourceSpecifier substringToIndex:firstSemicolon.location] : nil;
firstSemicolon.length ? [request.URL.resourceSpecifier substringToIndex:firstSemicolon.location] : nil;
// Send response
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL
@@ -72,7 +72,7 @@ RCT_EXPORT_MODULE()
// Load data
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:request.URL options:NSDataReadingMappedIfSafe error:&error];
if (data != nullptr) {
if (data) {
[delegate URLRequest:strongOp didReceiveData:data];
}
[delegate URLRequest:strongOp didCompleteWithError:error];
@@ -46,7 +46,7 @@ RCT_EXPORT_MODULE()
- (BOOL)isValid
{
// if session == nil and delegates != nil, we've been invalidated
return (_session != nullptr) || (_delegates == nullptr);
return _session || !_delegates;
}
#pragma mark - NSURLRequestHandler
@@ -67,7 +67,7 @@ RCT_EXPORT_MODULE()
{
std::lock_guard<std::mutex> lock(_mutex);
// Lazy setup
if ((_session == nullptr) && [self isValid]) {
if (!_session && [self isValid]) {
// You can override default NSURLSession instance property allowsCellularAccess (default value YES)
// by providing the following key to your RN project (edit ios/project/Info.plist file in Xcode):
// <key>ReactNetworkForceWifiOnly</key> <true/>
@@ -80,12 +80,12 @@ RCT_EXPORT_MODULE()
callbackQueue.maxConcurrentOperationCount = 1;
callbackQueue.underlyingQueue = [[_moduleRegistry moduleForName:"Networking"] methodQueue];
NSURLSessionConfiguration *configuration;
if (urlSessionConfigurationProvider != nullptr) {
if (urlSessionConfigurationProvider) {
configuration = urlSessionConfigurationProvider();
} else {
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// Set allowsCellularAccess to NO ONLY if key ReactNetworkForceWifiOnly exists AND its value is YES
if (useWifiOnly != nullptr) {
if (useWifiOnly) {
configuration.allowsCellularAccess = ![useWifiOnly boolValue];
}
[configuration setHTTPShouldSetCookies:YES];
@@ -10,9 +10,9 @@
#import "RCTNetworkConversions.h"
#import <React/RCTLog.h>
#import <react/networking/NetworkReporter.h>
#import <jsinspector-modern/network/NetworkReporter.h>
using namespace facebook::react;
using namespace facebook::react::jsinspector_modern;
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
namespace {
@@ -7,7 +7,7 @@
* @noformat
* @nolint
* @flow strict
* @generated SignedSource<<c0e57723772ea5f1aa8c3c897ac3c216>>
* @generated SignedSource<<deb7924d11c790f99448a1c2f0edddb9>>
*/
import type {
@@ -135,7 +135,6 @@ export type RenderRootOptions = {
error: mixed,
errorInfo: {+componentStack?: ?string},
) => void,
onDefaultTransitionIndicator?: () => void | (() => void),
};
/**
@@ -39,7 +39,7 @@ RCT_EXPORT_MODULE()
- (instancetype)initWithUserDefaults:(NSUserDefaults *)defaults
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_defaults = defaults;
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -84,7 +84,7 @@ RCT_EXPORT_METHOD(setValues : (NSDictionary *)values)
_ignoringUpdates = YES;
[values enumerateKeysAndObjectsUsingBlock:^(NSString *key, id json, BOOL *stop) {
id plist = [RCTConvert NSPropertyList:json];
if (plist != nullptr) {
if (plist) {
[self->_defaults setObject:plist forKey:key];
} else {
[self->_defaults removeObjectForKey:key];
@@ -141,7 +141,7 @@ RCT_EXPORT_METHOD(setTextAndSelection
RCTExecuteOnUIManagerQueue(^{
RCTBaseTextInputShadowView *shadowView =
(RCTBaseTextInputShadowView *)[self.bridge.uiManager shadowViewForReactTag:viewTag];
if (value != nullptr) {
if (value) {
[shadowView setText:value];
}
[self.bridge.uiManager setNeedsLayout];
@@ -16,7 +16,7 @@
+ (instancetype)newWithUnsafeDictionary:(NSDictionary<NSString *, id> *)dictionary
{
_RCTTypedModuleConstants *constants = [self new];
if (constants != nullptr) {
if (constants) {
constants->_dictionary = dictionary;
}
return constants;
-14
View File
@@ -211,18 +211,6 @@ let reactHermes = RNTarget(
]
)
/// React-networking.podspec
let reactNetworking = RNTarget(
name: .reactNetworking,
path: "ReactCommon/react/networking",
excludedPaths: ["tests"],
dependencies: [.reactNativeDependencies, .reactJsInspectorNetwork, .reactPerformanceTimeline],
defines: [
CXXSetting.define("REACT_NATIVE_DEBUGGER_ENABLED", to: "1", .when(configuration: BuildConfiguration.debug)),
CXXSetting.define("REACT_NATIVE_DEBUGGER_ENABLED_DEVONLY", to: "1", .when(configuration: BuildConfiguration.debug)),
]
)
/// React-performancecdpmetrics.podspec
let reactPerformanceCdpMetrics = RNTarget(
name: .reactPerformanceCdpMetrics,
@@ -578,7 +566,6 @@ let targets = [
reactNativeDependencies,
hermesPrebuilt,
reactJsiTooling,
reactNetworking,
reactPerformanceCdpMetrics,
reactPerformanceTimeline,
reactRuntimeScheduler,
@@ -750,7 +737,6 @@ extension String {
static let hermesPrebuilt = "hermes-prebuilt"
static let reactJsiTooling = "React-jsitooling"
static let reactNetworking = "React-networking"
static let reactPerformanceCdpMetrics = "React-performancecdpmetrics"
static let reactPerformanceTimeline = "React-performancetimeline"
static let reactRuntimeScheduler = "React-runtimescheduler"
@@ -53,7 +53,7 @@ using namespace facebook;
launchOptions:(nullable NSDictionary *)launchOptions
{
self = [super self];
if (self != nullptr) {
if (self) {
_uiManagerProxy = [[RCTUIManagerProxy alloc] initWithViewRegistry:viewRegistry];
_moduleRegistry = moduleRegistry;
_bundleManager = bundleManager;
@@ -75,7 +75,7 @@ using namespace facebook;
if (queue == RCTJSThread) {
_dispatchToJSThread(block);
} else if (queue != nullptr) {
} else if (queue) {
dispatch_async(queue, block);
}
}
@@ -427,7 +427,7 @@ using namespace facebook;
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
{
self = [super self];
if (self != nullptr) {
if (self) {
_viewRegistry = viewRegistry;
_legacyViewRegistry = [NSMutableDictionary new];
}
@@ -443,8 +443,8 @@ using namespace facebook;
{
[self logWarning:@"Please migrate to RCTViewRegistry: @synthesize viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED."
cmd:_cmd];
UIView *view = ([_viewRegistry viewForReactTag:reactTag] != nullptr) ? [_viewRegistry viewForReactTag:reactTag]
: [_legacyViewRegistry objectForKey:reactTag];
UIView *view = [_viewRegistry viewForReactTag:reactTag] ? [_viewRegistry viewForReactTag:reactTag]
: [_legacyViewRegistry objectForKey:reactTag];
return RCTPaperViewOrCurrentView(view);
}
@@ -457,7 +457,7 @@ using namespace facebook;
__weak __typeof(self) weakSelf = self;
RCTExecuteOnMainQueue(^{
__typeof(self) strongSelf = weakSelf;
if (strongSelf != nullptr) {
if (strongSelf) {
RCTUIManager *proxiedManager = (RCTUIManager *)strongSelf;
RCTComposedViewRegistry *composedViewRegistry =
[[RCTComposedViewRegistry alloc] initWithUIManager:proxiedManager
@@ -238,10 +238,11 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale)
- (void)interfaceOrientationDidChange
{
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
UIWindow *window = RCTKeyWindow();
UIInterfaceOrientation nextOrientation = window.windowScene.interfaceOrientation;
UIApplication *application = RCTSharedApplication();
UIInterfaceOrientation nextOrientation = RCTKeyWindow().windowScene.interfaceOrientation;
BOOL isRunningInFullScreen = window ? CGRectEqualToRect(window.frame, window.screen.bounds) : YES;
BOOL isRunningInFullScreen =
CGRectEqualToRect(application.delegate.window.frame, application.delegate.window.screen.bounds);
// We are catching here two situations for multitasking view:
// a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
// b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
@@ -66,7 +66,7 @@ void RCTMessageThread::runSync(std::function<void()> func)
void RCTMessageThread::tryFunc(const std::function<void()> &func)
{
NSError *error = tryAndReturnError(func);
if (error != nullptr) {
if (error) {
m_errorBlock(error);
}
}
@@ -41,7 +41,7 @@ class RCTObjcExecutor : public JSExecutor {
: m_jse(jse), m_errorBlock(errorBlock), m_delegate(std::move(delegate)), m_jsThread(std::move(jsThread))
{
m_jsCallback = ^(id json, NSError *error) {
if (error != nullptr) {
if (error) {
// Do not use "m_errorBlock" here as the bridge might be in the middle
// of invalidation as a result of error handling and "this" can be
// already deallocated.
@@ -81,7 +81,7 @@ class RCTObjcExecutor : public JSExecutor {
onComplete:^(NSError *error) {
RCTProfileEndFlowEvent();
if (error != nullptr) {
if (error) {
m_errorBlock(error);
return;
}
@@ -26,7 +26,7 @@ using namespace facebook::react;
- (instancetype)initWithCxxMethod:(const CxxModule::Method &)method
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_method = std::make_unique<CxxModule::Method>(method);
}
return self;
@@ -76,7 +76,7 @@ folly::dynamic RCTNativeModule::getConstants()
void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params, int callId)
{
id<RCTBridgeMethod> method = m_moduleData.methods[methodId];
if (method != nullptr) {
if (method) {
RCT_PROFILE_BEGIN_EVENT(
RCTProfileTagAlways,
@"[RCTNativeModule invoke]",
@@ -119,13 +119,13 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params, int
if (isSyncModule) {
block();
BridgeNativeModulePerfLogger::syncMethodCallReturnConversionEnd(moduleName, methodName);
} else if (queue != nullptr) {
} else if (queue) {
BridgeNativeModulePerfLogger::asyncMethodCallDispatch(moduleName, methodName);
dispatch_async(queue, block);
}
#ifdef RCT_DEV
if (queue == nullptr) {
if (!queue) {
RCTLog(
@"Attempted to invoke `%u` (method ID) on `%@` (NativeModule name) without a method queue.",
methodId,
@@ -153,7 +153,7 @@ static MethodCallResult invokeInner(
int callId,
SchedulingContext context)
{
if ((bridge == nullptr) || !bridge.valid || (moduleData == nullptr)) {
if (!bridge || !bridge.valid || !moduleData) {
if (context == Sync) {
/**
* NOTE: moduleName and methodName are "". This shouldn't be an issue because there can only be one ongoing sync
@@ -166,7 +166,7 @@ static MethodCallResult invokeInner(
}
id<RCTBridgeMethod> method = moduleData.methods[methodId];
if (RCT_DEBUG && (method == nullptr)) {
if (RCT_DEBUG && !method) {
RCTLogError(@"Unknown methodID: %ud for module: %@", methodId, moduleData.name);
}
@@ -24,14 +24,14 @@ static NSString *getServerHost(NSURL *bundleURL)
{
NSNumber *port = @8081;
NSString *portStr = [[[NSProcessInfo processInfo] environment] objectForKey:@"RCT_METRO_PORT"];
if ((portStr != nullptr) && [portStr length] > 0) {
if (portStr && [portStr length] > 0) {
port = [NSNumber numberWithInt:[portStr intValue]];
}
if ([bundleURL port] != nullptr) {
if ([bundleURL port]) {
port = [bundleURL port];
}
NSString *host = [bundleURL host];
if (host == nullptr) {
if (!host) {
host = @"localhost";
}
@@ -186,7 +186,7 @@ static void sendEventToAllConnections(NSString *event)
NSString *key = [inspectorURL absoluteString];
id<RCTInspectorPackagerConnectionProtocol> connection = socketConnections[key];
if ((connection == nullptr) || !connection.isConnected) {
if (!connection || !connection.isConnected) {
connection = [[RCTCxxInspectorPackagerConnection alloc] initWithURL:inspectorURL];
socketConnections[key] = connection;
@@ -21,7 +21,7 @@ using ListenerBlock = void (^)(RCTInspectorNetworkListener *);
- (instancetype)init
{
self = [super init];
if (self != nullptr) {
if (self) {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
self.executorsByTaskId = [NSMutableDictionary new];
@@ -63,7 +63,7 @@ using ListenerBlock = void (^)(RCTInspectorNetworkListener *);
- (void)withListenerForTask:(NSURLSessionTask *)task execute:(ListenerBlock)block
{
void (^executor)(ListenerBlock) = self.executorsByTaskId[@(task.taskIdentifier)];
if (executor != nullptr) {
if (executor) {
executor(block);
}
}
@@ -59,7 +59,7 @@ typedef void (^RCTConnectedHandler)(void);
/** Disconnects and removes all handlers. */
- (void)stop;
/** Reconnect with given packager server, if packagerServerHostPort has changed. */
/** Reconnect with given packager server. */
- (void)reconnect:(NSString *)packagerServerHostPort;
/**
@@ -160,7 +160,6 @@ static RCTReconnectingWebSocket *socketForLocation(NSString *const serverHostPor
- (void)bundleURLSettingsChanged
{
// Will only reconnect if `packagerServerHostPort` has actually changed
[self reconnect:[[RCTBundleURLProvider sharedSettings] packagerServerHostPort]];
}
@@ -103,7 +103,7 @@
if (_alertWindow == nil) {
_alertWindow = [[UIWindow alloc] initWithWindowScene:RCTKeyWindow().windowScene];
if (_alertWindow != nullptr) {
if (_alertWindow) {
_alertWindow.rootViewController = [UIViewController new];
_alertWindow.windowLevel = UIWindowLevelAlert + 1;
}
@@ -17,7 +17,7 @@
- (instancetype)init
{
if ((self = [super init]) == nullptr) {
if (!(self = [super init])) {
return nil;
}
_touchHandler = [RCTSurfaceTouchHandler new];
@@ -61,7 +61,7 @@
{
UIInterfaceOrientationMask appSupportedOrientationsMask =
[RCTSharedApplication() supportedInterfaceOrientationsForWindow:RCTKeyWindow()];
if ((_supportedInterfaceOrientations & appSupportedOrientationsMask) == 0u) {
if (!(_supportedInterfaceOrientations & appSupportedOrientationsMask)) {
RCTLogError(
@"Modal was presented with 0x%x orientations mask but the application only supports 0x%x."
@"Add more interface orientations to your app's Info.plist to fix this."
@@ -106,7 +106,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
BOOL _shouldAnimatePresentation;
BOOL _shouldPresent;
BOOL _isPresented;
BOOL _modalInPresentation;
}
- (instancetype)initWithFrame:(CGRect)frame
@@ -116,7 +115,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
_shouldAnimatePresentation = YES;
_isPresented = NO;
_modalInPresentation = YES;
}
return self;
@@ -128,7 +126,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
_viewController = [RCTFabricModalHostViewController new];
_viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
_viewController.delegate = self;
_viewController.modalInPresentation = _modalInPresentation;
_viewController.modalInPresentation = YES;
}
return _viewController;
}
@@ -154,7 +152,6 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
if (shouldBePresented) {
[self saveAccessibilityFocusedView];
self.viewController.presentationController.delegate = self;
self.viewController.modalInPresentation = _modalInPresentation;
_isPresented = YES;
[self presentViewController:self.viewController
@@ -279,8 +276,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
self.viewController.modalPresentationStyle = presentationConfiguration(newProps);
if (oldViewProps.allowSwipeDismissal != newProps.allowSwipeDismissal) {
_modalInPresentation = !newProps.allowSwipeDismissal;
self.viewController.modalInPresentation = _modalInPresentation;
self.viewController.modalInPresentation = !newProps.allowSwipeDismissal;
}
_shouldPresent = newProps.visible;
@@ -132,18 +132,18 @@ static Class<RCTComponentViewProtocol> RCTComponentViewClassWithName(const char
// Fallback 1: Call provider function for component view class.
Class<RCTComponentViewProtocol> klass = RCTComponentViewClassWithName(name.c_str());
if (klass != nullptr) {
if (klass) {
[self registerComponentViewClass:klass];
return;
}
// Fallback 2: Ask the provider and check in the dictionary provided
if (self.thirdPartyFabricComponentsProvider != nullptr) {
if (self.thirdPartyFabricComponentsProvider) {
// Test whether a provider has been passed to avoid potentially expensive conversions
// between C++ and ObjC strings.
NSString *objcName = [NSString stringWithCString:name.c_str() encoding:NSUTF8StringEncoding];
klass = self.thirdPartyFabricComponentsProvider.thirdPartyFabricComponents[objcName];
if (klass != nullptr) {
if (klass) {
[self registerComponentViewClass:klass];
return;
}
@@ -54,7 +54,7 @@ PlatformRunLoopObserver::PlatformRunLoopObserver(
mainRunLoopObserver_ = CFRunLoopObserverCreateWithHandler(
NULL /* allocator */,
toCFRunLoopActivity(activities_) /* activities */,
1u /* repeats */,
true /* repeats */,
0 /* order */,
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
auto strongOwner = owner.lock();
@@ -50,7 +50,7 @@ static CGRect insetRect(CGRect rect, CGFloat left, CGFloat top, CGFloat right, C
static CGColorRef colorRefFromSharedColor(const SharedColor &color)
{
CGColorRef colorRef = RCTUIColorFromSharedColor(color).CGColor;
return (colorRef != nullptr) ? colorRef : [UIColor blackColor].CGColor;
return colorRef ? colorRef : [UIColor blackColor].CGColor;
}
static CALayer *initBoxShadowLayer(const BoxShadow &shadow, CGSize layerSize)
@@ -32,7 +32,7 @@ std::unique_ptr<IWebSocket> RCTCxxInspectorPackagerConnectionDelegate::connectWe
std::weak_ptr<IWebSocketDelegate> delegate)
{
auto *adapter = [[RCTCxxInspectorWebSocketAdapter alloc] initWithURL:url delegate:delegate];
if (adapter == nullptr) {
if (!adapter) {
return nullptr;
}
return std::make_unique<WebSocket>(adapter);
@@ -34,7 +34,7 @@ NSString *NSStringFromUTF8StringView(std::string_view view)
@implementation RCTCxxInspectorWebSocketAdapter
- (instancetype)initWithURL:(const std::string &)url delegate:(std::weak_ptr<IWebSocketDelegate>)delegate
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_delegate = delegate;
_webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:NSStringFromUTF8StringView(url)]];
_webSocket.delegate = self;
@@ -49,7 +49,7 @@ NSString *NSStringFromUTF8StringView(std::string_view view)
NSString *messageStr = NSStringFromUTF8StringView(message);
dispatch_async(dispatch_get_main_queue(), ^{
RCTCxxInspectorWebSocketAdapter *strongSelf = weakSelf;
if (strongSelf != nullptr) {
if (strongSelf) {
[strongSelf->_webSocket sendString:messageStr error:NULL];
}
});
@@ -91,9 +91,9 @@ Pod::Spec.new do |s|
add_dependency(s, "React-RCTAnimation", :framework_name => 'RCTAnimation')
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp')
add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork')
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
add_dependency(s, "React-performancecdpmetrics", :framework_name => 'React_performancecdpmetrics')
add_dependency(s, "React-networking", :framework_name => 'React_networking')
add_dependency(s, "React-renderercss")
add_dependency(s, "React-RCTFBReactNativeSpec")
@@ -50,7 +50,7 @@ static SEL selectorForType(NSString *type)
bridge:(RCTBridge *)bridge
eventDispatcher:(id<RCTEventDispatcherProtocol>)eventDispatcher
{
if ((self = [super init]) != nullptr) {
if ((self = [super init])) {
_bridge = bridge;
_eventDispatcher = eventDispatcher;
_managerClass = managerClass;
@@ -71,12 +71,12 @@ static SEL selectorForType(NSString *type)
- (RCTViewManager *)manager
{
if ((_manager == nullptr) && [self isBridgeMode]) {
if (!_manager && [self isBridgeMode]) {
_manager = [_bridge moduleForClass:_managerClass];
} else if ((_manager == nullptr) && (_bridgelessViewManager == nullptr)) {
} else if (!_manager && !_bridgelessViewManager) {
_bridgelessViewManager = [_bridge moduleForClass:_managerClass];
}
return (_manager != nullptr) ? _manager : _bridgelessViewManager;
return _manager ? _manager : _bridgelessViewManager;
}
RCT_NOT_IMPLEMENTED(-(instancetype)init)
@@ -106,7 +106,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
{
json = RCTNilIfNull(json);
if (!isShadowView) {
if ((json == nullptr) && (_defaultView == nullptr)) {
if (!json && !_defaultView) {
// Only create default view if json is null
_defaultView = [self createViewWithTag:nil rootTag:nil];
}
@@ -130,11 +130,11 @@ static RCTPropBlock createEventSetter(
eventHandler = ^(NSDictionary *event) {
// The component no longer exists, we shouldn't send the event
id<RCTComponent> strongTarget = weakTarget;
if (strongTarget == nullptr) {
if (!strongTarget) {
return;
}
if (eventInterceptor != nullptr) {
if (eventInterceptor) {
eventInterceptor(propName, event, strongTarget.reactTag);
} else {
RCTComponentEvent *componentEvent = [[RCTComponentEvent alloc] initWithName:propName
@@ -158,13 +158,13 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
__block NSMutableData *defaultValue = nil;
return ^(id target, id json) {
if (target == nullptr) {
if (!target) {
return;
}
// Get default value
if (defaultValue == nullptr) {
if (json == nullptr) {
if (!defaultValue) {
if (!json) {
// We only set the defaultValue when we first pass a non-null
// value, so if the first value sent for a prop is null, it's
// a no-op (we'd be resetting it to its default when its
@@ -186,10 +186,10 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
// Get value
BOOL freeValueOnCompletion = NO;
void *value = defaultValue.mutableBytes;
if (json != nullptr) {
if (json) {
freeValueOnCompletion = YES;
value = malloc(typeSignature.methodReturnLength);
if (value == nullptr) {
if (!value) {
// CWE - 391 : Unchecked error condition
// https://www.cvedetails.com/cwe-details/391/Unchecked-Error-Condition.html
// https://eli.thegreenplace.net/2009/10/30/handling-out-of-memory-conditions-in-c
@@ -201,7 +201,7 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
}
// Set value
if (targetInvocation == nullptr) {
if (!targetInvocation) {
NSMethodSignature *signature = [target methodSignatureForSelector:setter];
targetInvocation = [NSInvocation invocationWithMethodSignature:signature];
targetInvocation.selector = setter;
@@ -252,7 +252,7 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
// Disect keypath
NSString *key = name;
NSArray<NSString *> *parts = [keyPath componentsSeparatedByString:@"."];
if (parts != nullptr) {
if (parts) {
key = parts.lastObject;
parts = [parts subarrayWithRange:(NSRange){0, parts.count - 1}];
}
@@ -275,7 +275,7 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
} else {
// Ordinary property handlers
NSMethodSignature *typeSignature = [[RCTConvert class] methodSignatureForSelector:type];
if (typeSignature == nullptr) {
if (!typeSignature) {
RCTLogError(@"No +[RCTConvert %@] function found.", NSStringFromSelector(type));
return ^(__unused id<RCTComponent> view, __unused id json) {
};
@@ -347,7 +347,7 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
{
RCTPropBlockDictionary *propBlocks = isShadowView ? _shadowPropBlocks : _viewPropBlocks;
RCTPropBlock propBlock = propBlocks[name];
if (propBlock == nullptr) {
if (!propBlock) {
propBlock = [self createPropBlock:name isShadowView:isShadowView];
#if RCT_DEBUG
@@ -381,7 +381,7 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
- (void)setProps:(NSDictionary<NSString *, id> *)props forView:(id<RCTComponent>)view isShadowView:(BOOL)isShadowView
{
if (view == nullptr) {
if (!view) {
return;
}
@@ -467,13 +467,13 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
// We need to handle both propConfig_* and propConfigShadow_* methods
const char *underscorePos = strchr(selectorName + strlen("propConfig"), '_');
if (underscorePos == nullptr) {
if (!underscorePos) {
continue;
}
NSString *name = @(underscorePos + 1);
NSString *type = ((NSArray<NSString *> * (*)(id, SEL)) objc_msgSend)(managerClass, selector)[0];
if (RCT_DEBUG && (propTypes[name] != nullptr) && ![propTypes[name] isEqualToString:type]) {
if (RCT_DEBUG && propTypes[name] && ![propTypes[name] isEqualToString:type]) {
RCTLogError(
@"Property '%@' of component '%@' redefined from '%@' "
"to '%@'",
@@ -2354,14 +2354,12 @@ public class com/facebook/react/fabric/mounting/SurfaceMountingManager {
public fun sendAccessibilityEvent (II)V
public fun setJSResponder (IIZ)V
public fun stopSurface ()V
public fun storeSynchronousMountPropsOverride (ILcom/facebook/react/bridge/ReadableMap;)V
public fun sweepActiveTouchForTag (I)V
public fun updateEventEmitter (ILcom/facebook/react/fabric/events/EventEmitterWrapper;)V
public fun updateLayout (IIIIIIII)V
public fun updateOverflowInset (IIIII)V
public fun updatePadding (IIIII)V
public fun updateProps (ILcom/facebook/react/bridge/ReadableMap;)V
public fun updatePropsSynchronously (ILcom/facebook/react/bridge/ReadableMap;)V
public fun updateState (ILcom/facebook/react/uimanager/StateWrapper;)V
}
@@ -39,9 +39,6 @@ val downloadsDir =
val thirdPartyNdkDir = File("$buildDir/third-party-ndk")
val reactNativeRootDir = projectDir.parent
val hermesV1Enabled =
rootProject.extensions.getByType(PrivateReactExtension::class.java).hermesV1Enabled.get()
// We put the publishing version from gradle.properties inside ext. so other
// subprojects can access it as well.
extra["publishing_version"] = project.findProperty("VERSION_NAME")?.toString()!!
@@ -568,10 +565,6 @@ android {
"-DCMAKE_POLICY_DEFAULT_CMP0069=NEW",
)
if (hermesV1Enabled) {
arguments("-DHERMES_V1_ENABLED=1")
}
targets(
"reactnative",
"jsi",
@@ -1,7 +1,5 @@
VERSION_NAME=1000.0.0
HERMES_VERSION_NAME=1000.0.0
react.internal.publishingGroup=com.facebook.react
react.internal.hermesPublishingGroup=com.facebook.hermes
android.useAndroidX=true
@@ -5,7 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
import com.facebook.react.internal.PrivateReactExtension
import com.facebook.react.tasks.internal.*
import de.undercouch.gradle.tasks.download.Download
import org.apache.tools.ant.taskdefs.condition.Os
@@ -51,8 +50,6 @@ fun getSDKManagerPath(): String {
}
}
val hermesV1Enabled =
rootProject.extensions.getByType(PrivateReactExtension::class.java).hermesV1Enabled.get()
val reactNativeRootDir = project(":packages:react-native:ReactAndroid").projectDir.parent
val customDownloadDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
val downloadsDir =
@@ -82,21 +79,12 @@ val hermesBuildOutputFileTree =
fileTree(hermesBuildDir.toString())
.include("**/*.cmake", "**/*.marks", "**/compiler_depends.ts", "**/Makefile", "**/link.txt")
val hermesVersionProvider: Provider<String> =
providers.provider {
var hermesVersion = if (hermesV1Enabled) "250829098.0.0-stable" else "main"
val hermesVersionFile =
File(
reactNativeRootDir,
if (hermesV1Enabled) "sdks/.hermesv1version" else "sdks/.hermesversion",
)
var hermesVersion = "main"
val hermesVersionFile = File(reactNativeRootDir, "sdks/.hermesversion")
if (hermesVersionFile.exists()) {
hermesVersion = hermesVersionFile.readText()
}
hermesVersion
}
if (hermesVersionFile.exists()) {
hermesVersion = hermesVersionFile.readText()
}
val ndkBuildJobs = Runtime.getRuntime().availableProcessors().toString()
val prefabHeadersDir = File("$buildDir/prefab-headers")
@@ -107,11 +95,7 @@ val jsiDir = File(reactNativeRootDir, "ReactCommon/jsi")
val downloadHermesDest = File(downloadsDir, "hermes.tar.gz")
val downloadHermes by
tasks.registering(Download::class) {
src(
providers.provider {
"https://github.com/facebook/hermes/tarball/${hermesVersionProvider.get()}"
}
)
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
onlyIfModified(true)
overwrite(true)
quiet(true)
@@ -167,7 +151,6 @@ val configureBuildForHermes by
"-B",
hermesBuildDir.toString(),
"-DJSI_DIR=" + jsiDir.absolutePath,
"-DCMAKE_BUILD_TYPE=Release",
)
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
cmakeCommandLine = cmakeCommandLine + "-GNMake Makefiles"
@@ -312,11 +295,7 @@ android {
// Therefore we're passing as build type Release, to provide a faster build.
// This has the (unlucky) side effect of letting AGP call the build
// tasks `configureCMakeRelease` while is actually building the debug flavor.
arguments(
"-DCMAKE_BUILD_TYPE=Release",
// For debug builds, explicitly enable the Hermes Debugger.
"-DHERMES_ENABLE_DEBUGGER=True",
)
arguments("-DCMAKE_BUILD_TYPE=Release")
}
}
}
@@ -791,8 +791,7 @@ public class FabricUIManager
@Override
public void execute(MountingManager mountingManager) {
try {
mountingManager.storeSynchronousMountPropsOverride(reactTag, props);
mountingManager.updatePropsSynchronously(reactTag, props);
mountingManager.updateProps(reactTag, props);
} catch (Exception ex) {
// TODO T42943890: Fix animations in Fabric and remove this try/catch?
// There might always be race conditions between surface teardown and
@@ -265,23 +265,13 @@ internal class MountingManager(
}
@UiThread
fun storeSynchronousMountPropsOverride(reactTag: Int, props: ReadableMap?) {
fun updateProps(reactTag: Int, props: ReadableMap?) {
assertOnUiThread()
if (props == null) {
return
}
getSurfaceManagerForViewEnforced(reactTag).storeSynchronousMountPropsOverride(reactTag, props)
}
@UiThread
fun updatePropsSynchronously(reactTag: Int, props: ReadableMap?) {
assertOnUiThread()
if (props == null) {
return
}
getSurfaceManagerForViewEnforced(reactTag).updatePropsSynchronously(reactTag, props)
getSurfaceManagerForViewEnforced(reactTag).updateProps(reactTag, props)
}
/**
@@ -27,14 +27,10 @@ import com.facebook.react.bridge.ReactNoCrashSoftException;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.RetryableMountingLayerException;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.common.mapbuffer.MapBuffer;
@@ -57,10 +53,7 @@ import com.facebook.react.uimanager.ViewManagerRegistry;
import com.facebook.react.uimanager.events.EventCategoryDef;
import com.facebook.systrace.Systrace;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
@@ -103,11 +96,6 @@ public class SurfaceMountingManager {
// This is null *until* StopSurface is called.
private SparseArrayCompat<Object> mTagSetForStoppedSurface;
// This is to make sure direct manipulation result will not be overridden by React update.
@ThreadConfined(UI)
private final SparseArrayCompat<Map<String, Object>> mTagToSynchronousMountProps =
new SparseArrayCompat<>();
private final int mSurfaceId;
public SurfaceMountingManager(
@@ -694,110 +682,13 @@ public class SurfaceMountingManager {
}
}
private static void overridePropsReadableMap(
Map<String, Object> patchMap, WritableMap outputReadableMap) {
for (Map.Entry<String, Object> entry : patchMap.entrySet()) {
String propKey = entry.getKey();
if (outputReadableMap.hasKey(propKey)) {
Object propValue = entry.getValue();
if (propKey.equals("transform")) {
assert (outputReadableMap.getType(propKey) == ReadableType.Array
&& propValue instanceof ArrayList);
WritableArray array = new WritableNativeArray();
for (Object item : (ArrayList<?>) propValue) {
if (item instanceof HashMap) {
WritableNativeMap itemMap = new WritableNativeMap();
for (Map.Entry<String, Object> itemEntry :
((HashMap<String, Object>) item).entrySet()) {
if (itemEntry.getValue() instanceof String) {
itemMap.putString(itemEntry.getKey(), (String) itemEntry.getValue());
} else if (itemEntry.getValue() instanceof Number) {
itemMap.putDouble(
itemEntry.getKey(), ((Number) itemEntry.getValue()).doubleValue());
}
}
array.pushMap(itemMap);
}
}
outputReadableMap.putArray(propKey, array);
} else if (propKey.equals("opacity")) {
assert (outputReadableMap.getType(propKey) == ReadableType.Number
&& propValue instanceof Number);
outputReadableMap.putDouble(propKey, ((Number) propValue).doubleValue());
}
}
}
}
private static Map<String, Object> getHashMapFromPropsReadableMap(ReadableMap readableMap) {
HashMap<String, Object> outputMap = new HashMap<>();
Iterator<Map.Entry<String, Object>> iter = readableMap.getEntryIterator();
while (iter.hasNext()) {
Map.Entry<String, Object> entry = iter.next();
String propKey = entry.getKey();
Object propValue = entry.getValue();
if (propKey.equals("transform") && propValue instanceof ReadableArray) {
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<>();
for (int i = 0; i < ((ReadableArray) propValue).size(); i++) {
ReadableMap map = ((ReadableArray) propValue).getMap(i);
if (map != null) {
arrayList.add(map.toHashMap());
}
}
outputMap.put(propKey, arrayList);
} else if (propKey.equals("opacity") && propValue instanceof Number) {
outputMap.put(propKey, ((Number) propValue).doubleValue());
}
}
return outputMap;
}
public void storeSynchronousMountPropsOverride(int reactTag, ReadableMap props) {
if (ReactNativeFeatureFlags.overrideBySynchronousMountPropsAtMountingAndroid()) {
Map<String, Object> propsMap = getHashMapFromPropsReadableMap(props);
if (mTagToSynchronousMountProps.containsKey(reactTag)) {
Map<String, Object> mergedPropsMap =
Assertions.assertNotNull(mTagToSynchronousMountProps.get(reactTag));
mergedPropsMap.putAll(propsMap);
mTagToSynchronousMountProps.put(reactTag, mergedPropsMap);
} else {
mTagToSynchronousMountProps.put(reactTag, propsMap);
}
}
}
public void updatePropsSynchronously(int reactTag, ReadableMap props) {
updateProps(reactTag, props, true);
}
public void updateProps(int reactTag, ReadableMap props) {
updateProps(reactTag, props, false);
}
@UiThread
private void updateProps(
int reactTag, ReadableMap props, Boolean shouldSkipSynchronousMountPropsOverride) {
if (isStopped()) {
return;
}
ViewState viewState = getViewState(reactTag);
if (ReactNativeFeatureFlags.overrideBySynchronousMountPropsAtMountingAndroid()
&& !shouldSkipSynchronousMountPropsOverride
&& mTagToSynchronousMountProps.containsKey(reactTag)) {
WritableMap modifiedProps = new WritableNativeMap();
modifiedProps.merge(props);
Map<String, Object> directPropsMap =
Assertions.assertNotNull(mTagToSynchronousMountProps.get(reactTag));
overridePropsReadableMap(directPropsMap, modifiedProps);
viewState.mCurrentProps = new ReactStylesDiffMap(modifiedProps);
} else {
viewState.mCurrentProps = new ReactStylesDiffMap(props);
}
viewState.mCurrentProps = new ReactStylesDiffMap(props);
View view = viewState.mView;
if (view == null) {
@@ -1166,11 +1057,6 @@ public class SurfaceMountingManager {
return;
}
if (ReactNativeFeatureFlags.overrideBySynchronousMountPropsAtMountingAndroid()
&& mTagToSynchronousMountProps.containsKey(reactTag)) {
mTagToSynchronousMountProps.remove(reactTag);
}
ViewState viewState = getNullableViewState(reactTag);
if (viewState == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<c217318f9f313103ca31d8e7698851d8>>
* @generated SignedSource<<a59b42b84160c18d214f8b2be76bc743>>
*/
/**
@@ -258,12 +258,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableViewRecycling(): Boolean = accessor.enableViewRecycling()
/**
* Enables View Recycling for <Image> via ReactViewGroup/ReactViewManager.
*/
@JvmStatic
public fun enableViewRecyclingForImage(): Boolean = accessor.enableViewRecyclingForImage()
/**
* Enables View Recycling for <ScrollView> via ReactViewGroup/ReactViewManager.
*/
@@ -324,12 +318,6 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun hideOffscreenVirtualViewsOnIOS(): Boolean = accessor.hideOffscreenVirtualViewsOnIOS()
/**
* Override props at mounting with synchronously mounted (i.e. direct manipulation) props from Native Animated.
*/
@JvmStatic
public fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean = accessor.overrideBySynchronousMountPropsAtMountingAndroid()
/**
* Enable the V2 in-app Performance Monitor. This flag is global and should not be changed across React Host lifetimes.
*/
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<4ed350d8dfa42caf27d346dfcfbed974>>
* @generated SignedSource<<37203dffb9421d1036aaeaeaa7319e28>>
*/
/**
@@ -58,7 +58,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableResourceTimingAPICache: Boolean? = null
private var enableViewCullingCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var enableViewRecyclingForImageCache: Boolean? = null
private var enableViewRecyclingForScrollViewCache: Boolean? = null
private var enableViewRecyclingForTextCache: Boolean? = null
private var enableViewRecyclingForViewCache: Boolean? = null
@@ -69,7 +68,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var fuseboxEnabledReleaseCache: Boolean? = null
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
private var perfMonitorV2EnabledCache: Boolean? = null
private var preparedTextCacheSizeCache: Double? = null
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
@@ -433,15 +431,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun enableViewRecyclingForImage(): Boolean {
var cached = enableViewRecyclingForImageCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableViewRecyclingForImage()
enableViewRecyclingForImageCache = cached
}
return cached
}
override fun enableViewRecyclingForScrollView(): Boolean {
var cached = enableViewRecyclingForScrollViewCache
if (cached == null) {
@@ -532,15 +521,6 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}
override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean {
var cached = overrideBySynchronousMountPropsAtMountingAndroidCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.overrideBySynchronousMountPropsAtMountingAndroid()
overrideBySynchronousMountPropsAtMountingAndroidCache = cached
}
return cached
}
override fun perfMonitorV2Enabled(): Boolean {
var cached = perfMonitorV2EnabledCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<6c201de02071a834e411b6761d7f863b>>
* @generated SignedSource<<9c0acc876e3205fe2ea181e71eb512c9>>
*/
/**
@@ -104,8 +104,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun enableViewRecycling(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecyclingForImage(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecyclingForScrollView(): Boolean
@DoNotStrip @JvmStatic public external fun enableViewRecyclingForText(): Boolean
@@ -126,8 +124,6 @@ public object ReactNativeFeatureFlagsCxxInterop {
@DoNotStrip @JvmStatic public external fun hideOffscreenVirtualViewsOnIOS(): Boolean
@DoNotStrip @JvmStatic public external fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean
@DoNotStrip @JvmStatic public external fun perfMonitorV2Enabled(): Boolean
@DoNotStrip @JvmStatic public external fun preparedTextCacheSize(): Double
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<7c4c3bf6b720f3e15fb97d8f1a4d74ba>>
* @generated SignedSource<<05bfed9fc7131062c8b16246986fc999>>
*/
/**
@@ -99,8 +99,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun enableViewRecycling(): Boolean = false
override fun enableViewRecyclingForImage(): Boolean = true
override fun enableViewRecyclingForScrollView(): Boolean = false
override fun enableViewRecyclingForText(): Boolean = true
@@ -121,8 +119,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
override fun hideOffscreenVirtualViewsOnIOS(): Boolean = false
override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean = false
override fun perfMonitorV2Enabled(): Boolean = false
override fun preparedTextCacheSize(): Double = 200.0
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<57fca2370d6b3f1edf7045a0b4c94350>>
* @generated SignedSource<<9a18369464f81c3d03f2702716dfdb29>>
*/
/**
@@ -62,7 +62,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableResourceTimingAPICache: Boolean? = null
private var enableViewCullingCache: Boolean? = null
private var enableViewRecyclingCache: Boolean? = null
private var enableViewRecyclingForImageCache: Boolean? = null
private var enableViewRecyclingForScrollViewCache: Boolean? = null
private var enableViewRecyclingForTextCache: Boolean? = null
private var enableViewRecyclingForViewCache: Boolean? = null
@@ -73,7 +72,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var fuseboxEnabledReleaseCache: Boolean? = null
private var fuseboxNetworkInspectionEnabledCache: Boolean? = null
private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null
private var overrideBySynchronousMountPropsAtMountingAndroidCache: Boolean? = null
private var perfMonitorV2EnabledCache: Boolean? = null
private var preparedTextCacheSizeCache: Double? = null
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
@@ -475,16 +473,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun enableViewRecyclingForImage(): Boolean {
var cached = enableViewRecyclingForImageCache
if (cached == null) {
cached = currentProvider.enableViewRecyclingForImage()
accessedFeatureFlags.add("enableViewRecyclingForImage")
enableViewRecyclingForImageCache = cached
}
return cached
}
override fun enableViewRecyclingForScrollView(): Boolean {
var cached = enableViewRecyclingForScrollViewCache
if (cached == null) {
@@ -585,16 +573,6 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}
override fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean {
var cached = overrideBySynchronousMountPropsAtMountingAndroidCache
if (cached == null) {
cached = currentProvider.overrideBySynchronousMountPropsAtMountingAndroid()
accessedFeatureFlags.add("overrideBySynchronousMountPropsAtMountingAndroid")
overrideBySynchronousMountPropsAtMountingAndroidCache = cached
}
return cached
}
override fun perfMonitorV2Enabled(): Boolean {
var cached = perfMonitorV2EnabledCache
if (cached == null) {
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<ef31518f0fe8ff6f6a5c15936cab9d87>>
* @generated SignedSource<<845b2ee5edc9aedbdbd052d9a930f666>>
*/
/**
@@ -99,8 +99,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun enableViewRecycling(): Boolean
@DoNotStrip public fun enableViewRecyclingForImage(): Boolean
@DoNotStrip public fun enableViewRecyclingForScrollView(): Boolean
@DoNotStrip public fun enableViewRecyclingForText(): Boolean
@@ -121,8 +119,6 @@ public interface ReactNativeFeatureFlagsProvider {
@DoNotStrip public fun hideOffscreenVirtualViewsOnIOS(): Boolean
@DoNotStrip public fun overrideBySynchronousMountPropsAtMountingAndroid(): Boolean
@DoNotStrip public fun perfMonitorV2Enabled(): Boolean
@DoNotStrip public fun preparedTextCacheSize(): Double
@@ -18,7 +18,6 @@ import com.facebook.react.bridge.WritableArray
import com.facebook.react.common.SystemClock.currentTimeMillis
import com.facebook.react.common.SystemClock.nanoTime
import com.facebook.react.common.SystemClock.uptimeMillis
import com.facebook.react.common.annotations.internal.LegacyArchitecture
import com.facebook.react.devsupport.interfaces.DevSupportManager
import com.facebook.react.jstasks.HeadlessJsTaskContext
import com.facebook.react.jstasks.HeadlessJsTaskEventListener
@@ -111,7 +110,6 @@ public open class JavaTimerManager(
clearChoreographerIdleCallback()
}
@LegacyArchitecture
private fun maybeSetChoreographerIdleCallback() {
synchronized(idleCallbackGuard) {
if (sendIdleEvents) {
@@ -120,7 +118,6 @@ public open class JavaTimerManager(
}
}
@LegacyArchitecture
private fun maybeIdleCallback() {
if (isPaused.get() && !isRunningTasks.get()) {
clearFrameCallback()
@@ -148,7 +145,6 @@ public open class JavaTimerManager(
}
}
@LegacyArchitecture
private fun setChoreographerIdleCallback() {
if (!frameIdleCallbackPosted) {
reactChoreographer.postFrameCallback(
@@ -159,7 +155,6 @@ public open class JavaTimerManager(
}
}
@LegacyArchitecture
private fun clearChoreographerIdleCallback() {
if (frameIdleCallbackPosted) {
reactChoreographer.removeFrameCallback(
@@ -240,7 +235,6 @@ public open class JavaTimerManager(
}
@DoNotStrip
@LegacyArchitecture
public open fun setSendIdleEvents(sendIdleEvents: Boolean) {
synchronized(idleCallbackGuard) { this.sendIdleEvents = sendIdleEvents }
UiThreadUtil.runOnUiThread {
@@ -334,7 +328,6 @@ public open class JavaTimerManager(
}
}
@LegacyArchitecture
private inner class IdleCallbackRunnable(private val frameStartTime: Long) : Runnable {
@Volatile private var isCancelled = false
@@ -8,14 +8,15 @@
package com.facebook.react.runtime
import com.facebook.common.logging.FLog
import java.util.Collections
internal class ReactHostStateTracker(private val id: Int) {
internal class BridgelessReactStateTracker(private val shouldTrackStates: Boolean) {
private val states = Collections.synchronizedList(mutableListOf<String>())
fun enterState(method: String, message: String? = null) {
if (message == null) {
FLog.w(TAG, "ReactHost{%d}.%s", id, method)
} else {
FLog.w(TAG, "ReactHost{%d}.%s: %s", id, method, message)
fun enterState(state: String) {
FLog.w(TAG, state)
if (shouldTrackStates) {
states.add(state)
}
}
@@ -7,20 +7,15 @@
package com.facebook.react.runtime
import com.facebook.jni.HybridClassBase
import com.facebook.jni.annotations.DoNotStrip
import com.facebook.jni.HybridData
import com.facebook.jni.annotations.DoNotStripAny
import com.facebook.react.bridge.WritableArray
import com.facebook.react.bridge.WritableNativeArray
import com.facebook.react.modules.core.JavaScriptTimerExecutor
import com.facebook.soloader.SoLoader
@DoNotStrip
internal class JSTimerExecutor() : HybridClassBase(), JavaScriptTimerExecutor {
init {
initHybrid()
}
private external fun initHybrid()
@DoNotStripAny
internal class JSTimerExecutor(private val mHybridData: HybridData) : JavaScriptTimerExecutor {
private external fun callTimers(timerIDs: WritableNativeArray)
@@ -128,12 +128,12 @@ public class ReactHostImpl(
private var reactInstance: ReactInstance? = null
private val bridgelessReactContextRef = BridgelessAtomicRef<BridgelessReactContext>()
private val id = counter.getAndIncrement()
private val activity = AtomicReference<Activity?>()
private val lastUsedActivityRef = AtomicReference(WeakReference<Activity?>(null))
private val stateTracker = ReactHostStateTracker(id)
private val reactLifecycleStateManager = ReactLifecycleStateManager(stateTracker)
private val bridgelessReactStateTracker = BridgelessReactStateTracker(ReactBuildConfig.DEBUG)
private val reactLifecycleStateManager = ReactLifecycleStateManager(bridgelessReactStateTracker)
private val id = counter.getAndIncrement()
private var memoryPressureListener: MemoryPressureListener? = null
private var defaultHardwareBackBtnHandler: DefaultHardwareBackBtnHandler? = null
@@ -178,11 +178,11 @@ public class ReactHostImpl(
/** Initialize and run a React Native surface in a background without mounting real views. */
internal fun prerenderSurface(surface: ReactSurfaceImpl): TaskInterface<Void> {
val method = "prerenderSurface(surfaceId = ${surface.surfaceID})"
stateTracker.enterState(method, "Schedule")
log(method, "Schedule")
attachSurface(surface)
return callAfterGetOrCreateReactInstance(method, bgExecutor) { reactInstance: ReactInstance ->
stateTracker.enterState(method, "Execute")
log(method, "Execute")
reactInstance.prerenderSurface(surface)
}
}
@@ -195,11 +195,11 @@ public class ReactHostImpl(
*/
internal fun startSurface(surface: ReactSurfaceImpl): TaskInterface<Void> {
val method = "startSurface(surfaceId = ${surface.surfaceID})"
stateTracker.enterState(method, "Schedule")
log(method, "Schedule")
attachSurface(surface)
return callAfterGetOrCreateReactInstance(method, bgExecutor) { reactInstance: ReactInstance ->
stateTracker.enterState(method, "Execute")
log(method, "Execute")
reactInstance.startSurface(surface)
}
}
@@ -212,11 +212,11 @@ public class ReactHostImpl(
*/
internal fun stopSurface(surface: ReactSurfaceImpl): TaskInterface<Void> {
val method = "stopSurface(surfaceId = ${surface.surfaceID})"
stateTracker.enterState(method, "Schedule")
log(method, "Schedule")
detachSurface(surface)
return callWithExistingReactInstance(method, bgExecutor) { reactInstance: ReactInstance ->
stateTracker.enterState(method, "Execute")
log(method, "Execute")
reactInstance.stopSurface(surface)
}
.makeVoid()
@@ -238,7 +238,8 @@ public class ReactHostImpl(
@ThreadConfined(ThreadConfined.UI)
override fun onHostResume(activity: Activity?) {
stateTracker.enterState("onHostResume(activity)")
val method = "onHostResume(activity)"
log(method)
currentActivity = activity
@@ -248,7 +249,8 @@ public class ReactHostImpl(
@ThreadConfined(ThreadConfined.UI)
override fun onHostLeaveHint(activity: Activity?) {
stateTracker.enterState("onUserLeaveHint(activity)")
val method = "onUserLeaveHint(activity)"
log(method)
currentReactContext?.onUserLeaveHint(activity)
}
@@ -256,7 +258,7 @@ public class ReactHostImpl(
@ThreadConfined(ThreadConfined.UI)
override fun onHostPause(activity: Activity?) {
val method = "onHostPause(activity)"
stateTracker.enterState(method)
log(method)
val currentActivity = this.currentActivity
if (currentActivity != null) {
@@ -267,7 +269,7 @@ public class ReactHostImpl(
val isNotSameActivityMessage =
"Pausing an activity that is not the current activity, this is incorrect! Current activity: $currentActivityClass Paused activity: $activityClass"
if (ReactNativeFeatureFlags.skipActivityIdentityAssertionOnHostPause()) {
FLog.w(TAG, method, isNotSameActivityMessage)
log(method, isNotSameActivityMessage)
} else {
Assertions.assertCondition(isSameActivity, isNotSameActivityMessage)
}
@@ -282,7 +284,8 @@ public class ReactHostImpl(
/** To be called when the host activity is paused. */
@ThreadConfined(ThreadConfined.UI)
override fun onHostPause() {
stateTracker.enterState("onHostPause()")
val method = "onHostPause()"
log(method)
maybeEnableDevSupport(false)
defaultHardwareBackBtnHandler = null
@@ -292,7 +295,8 @@ public class ReactHostImpl(
/** To be called when the host activity is destroyed. */
@ThreadConfined(ThreadConfined.UI)
override fun onHostDestroy() {
stateTracker.enterState("onHostDestroy()")
val method = "onHostDestroy()"
log(method)
maybeEnableDevSupport(false)
moveToHostDestroy(currentReactContext)
@@ -300,7 +304,8 @@ public class ReactHostImpl(
@ThreadConfined(ThreadConfined.UI)
override fun onHostDestroy(activity: Activity?) {
stateTracker.enterState("onHostDestroy(activity)")
val method = "onHostDestroy(activity)"
log(method)
val currentActivity = this.currentActivity
@@ -378,7 +383,7 @@ public class ReactHostImpl(
{
val reloadTask =
(destroyTask?.let { destroyTask ->
stateTracker.enterState(
log(
"reload()",
"Waiting for destroy to finish, before reloading React Native.",
)
@@ -480,7 +485,7 @@ public class ReactHostImpl(
{
val reloadTask = reloadTask
if (reloadTask != null) {
stateTracker.enterState(
log(
"destroy()",
"Reloading React Native. Waiting for reload to finish before destroying React Native.",
)
@@ -666,20 +671,20 @@ public class ReactHostImpl(
internal fun loadBundle(bundleLoader: JSBundleLoader): Task<Boolean> {
val method = "loadBundle()"
stateTracker.enterState(method, "Schedule")
log(method, "Schedule")
return callWithExistingReactInstance(method) { reactInstance: ReactInstance ->
stateTracker.enterState(method, "Execute")
log(method, "Execute")
reactInstance.loadJSBundle(bundleLoader)
}
}
internal fun registerSegment(segmentId: Int, path: String, callback: Callback?): Task<Boolean> {
val method = "registerSegment(segmentId = \"$segmentId\", path = \"$path\")"
stateTracker.enterState(method, "Schedule")
log(method, "Schedule")
return callWithExistingReactInstance(method) { reactInstance: ReactInstance ->
stateTracker.enterState(method, "Execute")
log(method, "Execute")
reactInstance.registerSegment(segmentId, path)
checkNotNull(callback).invoke()
}
@@ -687,7 +692,7 @@ public class ReactHostImpl(
internal fun handleHostException(e: Exception) {
val method = "handleHostException(message = \"${e.message}\")"
stateTracker.enterState(method)
log(method)
if (useDevSupport) {
devSupportManager.handleException(e)
@@ -717,12 +722,12 @@ public class ReactHostImpl(
}
internal fun attachSurface(surface: ReactSurfaceImpl) {
stateTracker.enterState("attachSurface(surfaceId = ${surface.surfaceID})")
log("attachSurface(surfaceId = ${surface.surfaceID})")
synchronized(attachedSurfaces) { attachedSurfaces.add(surface) }
}
internal fun detachSurface(surface: ReactSurfaceImpl) {
stateTracker.enterState("detachSurface(surfaceId = ${surface.surfaceID})")
log("detachSurface(surfaceId = ${surface.surfaceID})")
synchronized(attachedSurfaces) { attachedSurfaces.remove(surface) }
}
@@ -752,7 +757,8 @@ public class ReactHostImpl(
return it
}
stateTracker.enterState("getOrCreateStartTask()", "Schedule")
val method = "getOrCreateStartTask()"
log(method, "Schedule")
if (ReactBuildConfig.DEBUG) {
Assertions.assertCondition(
ReactNativeNewArchitectureFeatureFlags.enableBridgelessArchitecture(),
@@ -814,7 +820,7 @@ public class ReactHostImpl(
throwable: Throwable? = null,
) {
val method = "raiseSoftException($callingMethod)"
stateTracker.enterState(method, message)
log(method, message)
ReactSoftExceptionLogger.logSoftException(
TAG,
ReactNoCrashSoftException("$method: $message", throwable),
@@ -869,6 +875,14 @@ public class ReactHostImpl(
executor,
)
private fun getOrCreateReactContext(): BridgelessReactContext {
val method = "getOrCreateReactContext()"
return bridgelessReactContextRef.getOrCreate {
log(method, "Creating BridgelessReactContext")
BridgelessReactContext(context, this)
}
}
/**
* Entrypoint to create the ReactInstance.
*
@@ -889,14 +903,14 @@ public class ReactHostImpl(
): Task<ReactInstance> {
val method = "waitThenCallGetOrCreateReactInstanceTaskWithRetries"
reloadTask?.let { task ->
stateTracker.enterState(method, "React Native is reloading. Return reload task.")
log(method, "React Native is reloading. Return reload task.")
return task
}
destroyTask?.let { task ->
val shouldTryAgain = tryNum < maxTries
if (shouldTryAgain) {
stateTracker.enterState(
log(
method,
"React Native is tearing down.Wait for teardown to finish, before trying again (try count = $tryNum).",
)
@@ -924,10 +938,10 @@ public class ReactHostImpl(
@ThreadConfined("ReactHost")
private fun getOrCreateReactInstanceTask(): Task<ReactInstance> {
val method = "getOrCreateReactInstanceTask()"
stateTracker.enterState(method)
log(method)
return createReactInstanceTaskRef.getOrCreate {
stateTracker.enterState(method, "Start")
log(method, "Start")
Assertions.assertCondition(
!hostInvalidated,
"Cannot start a new ReactInstance on an invalidated ReactHost",
@@ -942,14 +956,10 @@ public class ReactHostImpl(
jsBundleLoader.onSuccess(
{ task ->
val bundleLoader = checkNotNull(task.getResult())
val reactContext =
bridgelessReactContextRef.getOrCreate {
stateTracker.enterState(method, "Creating BridgelessReactContext")
BridgelessReactContext(context, this)
}
val reactContext = getOrCreateReactContext()
reactContext.jsExceptionHandler = devSupportManager
stateTracker.enterState(method, "Creating ReactInstance")
log(method, "Creating ReactInstance")
val instance =
ReactInstance(
reactContext,
@@ -970,13 +980,10 @@ public class ReactHostImpl(
// as TurboModuleManager will handle any concurrent access
instance.initializeEagerTurboModules()
stateTracker.enterState(method, "Loading JS Bundle")
log(method, "Loading JS Bundle")
instance.loadJSBundle(bundleLoader)
stateTracker.enterState(
method,
"DevSupportManager.onNewReactContextCreated()",
)
log(method, "Calling DevSupportManagerBase.onNewReactContextCreated(reactContext)")
devSupportManager.onNewReactContextCreated(reactContext)
reactContext.runOnJSQueueThread {
@@ -1033,7 +1040,7 @@ public class ReactHostImpl(
reactLifecycleStateManager.resumeReactContextIfHostResumed(reactContext, currentActivity)
}
stateTracker.enterState(method, "Executing ReactInstanceEventListeners")
log(method, "Executing ReactInstanceEventListeners")
for (listener in reactInstanceEventListeners) {
listener.onReactContextInitialized(reactContext)
}
@@ -1046,7 +1053,8 @@ public class ReactHostImpl(
private val jsBundleLoader: Task<JSBundleLoader>
get() {
stateTracker.enterState("getJSBundleLoader()")
val method = "getJSBundleLoader()"
log(method)
if (useDevSupport && allowPackagerServerAccess) {
return isMetroRunning.onSuccessTask(
@@ -1085,13 +1093,13 @@ public class ReactHostImpl(
private val isMetroRunning: Task<Boolean>
get() {
val method = "isMetroRunning()"
stateTracker.enterState(method)
log(method)
val taskCompletionSource = TaskCompletionSource<Boolean>()
val asyncDevSupportManager = devSupportManager
asyncDevSupportManager.isPackagerRunning { packagerIsRunning: Boolean ->
stateTracker.enterState(method, "Async result = $packagerIsRunning")
log(method, "Async result = $packagerIsRunning")
taskCompletionSource.setResult(packagerIsRunning)
}
@@ -1100,7 +1108,7 @@ public class ReactHostImpl(
private fun loadJSBundleFromMetro(): Task<JSBundleLoader> {
val method = "loadJSBundleFromMetro()"
stateTracker.enterState(method)
log(method)
val taskCompletionSource = TaskCompletionSource<JSBundleLoader>()
val asyncDevSupportManager = devSupportManager as DevSupportManagerBase
@@ -1113,7 +1121,7 @@ public class ReactHostImpl(
bundleURL,
object : BundleLoadCallback {
override fun onSuccess() {
stateTracker.enterState(method, "Creating BundleLoader")
log(method, "Creating BundleLoader")
val bundleLoader =
JSBundleLoader.createCachedBundleFromNetworkLoader(
bundleURL,
@@ -1131,8 +1139,16 @@ public class ReactHostImpl(
return taskCompletionSource.task
}
private fun log(method: String, message: String) {
bridgelessReactStateTracker.enterState("ReactHost{$id}.$method: $message")
}
private fun log(method: String) {
bridgelessReactStateTracker.enterState("ReactHost{$id}.$method")
}
private fun stopAttachedSurfaces(method: String, reactInstance: ReactInstance) {
stateTracker.enterState(method, "Stopping all React Native surfaces")
log(method, "Stopping all React Native surfaces")
synchronized(attachedSurfaces) {
for (surface in attachedSurfaces) {
reactInstance.stopSurface(surface)
@@ -1142,7 +1158,7 @@ public class ReactHostImpl(
}
private fun startAttachedSurfaces(method: String, reactInstance: ReactInstance) {
stateTracker.enterState(method, "Restarting previously running React Native Surfaces")
log(method, "Restarting previously running React Native Surfaces")
synchronized(attachedSurfaces) {
for (surface in attachedSurfaces) {
reactInstance.startSurface(surface)
@@ -1209,7 +1225,7 @@ public class ReactHostImpl(
@ThreadConfined("ReactHost")
private fun getOrCreateReloadTask(reason: String): Task<ReactInstance> {
val method = "getOrCreateReloadTask()"
stateTracker.enterState(method)
log(method)
// Log how React Native is destroyed
// TODO(T136397487): Remove after Venice is shipped to 100%
@@ -1223,11 +1239,11 @@ public class ReactHostImpl(
// When using the immediate executor, we want to avoid scheduling any further work immediately
// when destruction is kicked off.
stateTracker.enterState(method, "Resetting createReactInstance task ref")
log(method, "Resetting createReactInstance task ref")
return createReactInstanceTaskRef.andReset
.continueWithTask(
{ task ->
stateTracker.enterState(method, "Starting React Native reload")
log(method, "Starting React Native reload")
val reactInstance = taskUnwrapper(task, "1: Starting reload")
unregisterInstanceFromInspector(reactInstance)
@@ -1241,7 +1257,7 @@ public class ReactHostImpl(
reactContext != null &&
reactLifecycleStateManager.lifecycleState == LifecycleState.RESUMED
) {
stateTracker.enterState(method, "Calling ReactContext.onHostPause()")
log(method, "Calling ReactContext.onHostPause()")
reactContext.onHostPause()
}
Task.forResult(reactInstance)
@@ -1268,24 +1284,21 @@ public class ReactHostImpl(
}
memoryPressureListener?.let { listener ->
stateTracker.enterState(method, "Removing memory pressure listener")
log(method, "Removing memory pressure listener")
memoryPressureRouter.removeMemoryPressureListener(listener)
}
val reactContext = bridgelessReactContextRef.value
if (reactContext != null) {
stateTracker.enterState(method, "Resetting ReactContext ref")
log(method, "Resetting ReactContext ref")
bridgelessReactContextRef.reset()
stateTracker.enterState(method, "Destroying ReactContext")
log(method, "Destroying ReactContext")
reactContext.destroy()
}
if (useDevSupport && reactContext != null) {
stateTracker.enterState(
method,
"Calling DevSupportManager.onReactInstanceDestroyed(reactContext)",
)
log(method, "Calling DevSupportManager.onReactInstanceDestroyed(reactContext)")
devSupportManager.onReactInstanceDestroyed(reactContext)
}
task
@@ -1298,14 +1311,14 @@ public class ReactHostImpl(
if (reactInstance == null) {
raiseSoftException(method, "Skipping ReactInstance.destroy(): ReactInstance null")
} else {
stateTracker.enterState(method, "Resetting ReactInstance ptr")
log(method, "Resetting ReactInstance ptr")
this.reactInstance = null
stateTracker.enterState(method, "Destroying ReactInstance")
log(method, "Destroying ReactInstance")
reactInstance.destroy()
}
stateTracker.enterState(method, "Resetting start task ref")
log(method, "Resetting start task ref")
startTask = null
// Kickstart a new ReactInstance create
@@ -1342,7 +1355,7 @@ public class ReactHostImpl(
)
}
stateTracker.enterState(method, "Resetting reload task ref")
log(method, "Resetting reload task ref")
reloadTask = null
task
},
@@ -1364,7 +1377,7 @@ public class ReactHostImpl(
@ThreadConfined("ReactHost")
private fun getOrCreateDestroyTask(reason: String, ex: Exception?): Task<Void> {
val method = "getOrCreateDestroyTask()"
stateTracker.enterState(method)
log(method)
// Log how React Native is destroyed
// TODO(T136397487): Remove after Venice is shipped to 100%
@@ -1378,11 +1391,11 @@ public class ReactHostImpl(
// When using the immediate executor, we want to avoid scheduling any further work immediately
// when destruction is kicked off.
stateTracker.enterState(method, "Resetting createReactInstance task ref")
log(method, "Resetting createReactInstance task ref")
return createReactInstanceTaskRef.andReset
.continueWithTask(
{ task: Task<ReactInstance> ->
stateTracker.enterState(method, "Starting React Native destruction")
log(method, "Starting React Native destruction")
val reactInstance = taskUnwrapper(task, "1: Starting destroy")
unregisterInstanceFromInspector(reactInstance)
@@ -1397,7 +1410,7 @@ public class ReactHostImpl(
// Step 1: Destroy DevSupportManager
if (useDevSupport) {
stateTracker.enterState(method, "DevSupportManager cleanup")
log(method, "DevSupportManager cleanup")
// TODO(T137233065): Disable DevSupportManager here
devSupportManager.stopInspector()
}
@@ -1408,7 +1421,7 @@ public class ReactHostImpl(
}
// Step 2: Move React Native to onHostDestroy()
stateTracker.enterState(method, "Move ReactHost to onHostDestroy()")
log(method, "Move ReactHost to onHostDestroy()")
reactLifecycleStateManager.moveToOnHostDestroy(reactContext)
Task.forResult<ReactInstance>(reactInstance)
},
@@ -1441,14 +1454,14 @@ public class ReactHostImpl(
}
// Step 4: De-register the memory pressure listener
stateTracker.enterState(method, "Destroying MemoryPressureRouter")
log(method, "Destroying MemoryPressureRouter")
memoryPressureRouter.destroy(context)
if (reactContext != null) {
stateTracker.enterState(method, "Resetting ReactContext ref")
log(method, "Resetting ReactContext ref")
bridgelessReactContextRef.reset()
stateTracker.enterState(method, "Destroying ReactContext")
log(method, "Destroying ReactContext")
reactContext.destroy()
}
@@ -1467,15 +1480,17 @@ public class ReactHostImpl(
if (reactInstance == null) {
raiseSoftException(method, "Skipping ReactInstance.destroy(): ReactInstance null")
} else {
stateTracker.enterState(method, "Resetting ReactInstance ptr")
log(method, "Resetting ReactInstance ptr")
this.reactInstance = null
stateTracker.enterState(method, "Destroying ReactInstance")
log(method, "Destroying ReactInstance")
reactInstance.destroy()
}
stateTracker.enterState(method, "Resetting start/destroy task ref")
log(method, "Resetting start task ref")
startTask = null
log(method, "Resetting destroy task ref")
destroyTask = null
task
},
@@ -76,6 +76,7 @@ import java.util.ArrayList
import java.util.HashMap
import java.util.HashSet
import kotlin.collections.Collection
import kotlin.jvm.JvmStatic
/**
* A replacement for [com.facebook.react.bridge.CatalystInstance] responsible for creating and
@@ -125,7 +126,7 @@ internal class ReactInstance(
ReactChoreographer.initialize(AndroidChoreographerProvider.getInstance())
devSupportManager.startInspector()
val jsTimerExecutor = JSTimerExecutor()
val jsTimerExecutor = createJSTimerExecutor()
javaTimerManager =
JavaTimerManager(
context,
@@ -181,6 +182,7 @@ internal class ReactInstance(
getJSCallInvokerHolder(),
getNativeMethodCallInvokerHolder(),
)
Systrace.endSection(Systrace.TRACE_TAG_REACT)
// Set up Fabric
@@ -631,5 +633,7 @@ internal class ReactInstance(
SystraceMessage.endSection(Systrace.TRACE_TAG_REACT).flush()
}
}
@JvmStatic @DoNotStrip private external fun createJSTimerExecutor(): JSTimerExecutor
}
}
@@ -13,7 +13,9 @@ import com.facebook.infer.annotation.ThreadConfined.UI
import com.facebook.react.bridge.ReactContext
import com.facebook.react.common.LifecycleState
internal class ReactLifecycleStateManager(private val stateTracker: ReactHostStateTracker) {
internal class ReactLifecycleStateManager(
private val bridgelessReactStateTracker: BridgelessReactStateTracker
) {
private var state: LifecycleState = LifecycleState.BEFORE_CREATE
val lifecycleState: LifecycleState
@@ -22,7 +24,7 @@ internal class ReactLifecycleStateManager(private val stateTracker: ReactHostSta
@ThreadConfined(UI)
fun resumeReactContextIfHostResumed(currentContext: ReactContext, activity: Activity?) {
if (state == LifecycleState.RESUMED) {
stateTracker.enterState("ReactContext.onHostResume()")
bridgelessReactStateTracker.enterState("ReactContext.onHostResume()")
currentContext.onHostResume(activity)
}
}
@@ -34,7 +36,7 @@ internal class ReactLifecycleStateManager(private val stateTracker: ReactHostSta
}
currentContext?.let { context ->
stateTracker.enterState("ReactContext.onHostResume()")
bridgelessReactStateTracker.enterState("ReactContext.onHostResume()")
context.onHostResume(activity)
}
state = LifecycleState.RESUMED
@@ -46,13 +48,13 @@ internal class ReactLifecycleStateManager(private val stateTracker: ReactHostSta
when (state) {
LifecycleState.BEFORE_CREATE -> {
// TODO: Investigate if we can remove this transition.
stateTracker.enterState("ReactContext.onHostResume()")
bridgelessReactStateTracker.enterState("ReactContext.onHostResume()")
it.onHostResume(activity)
stateTracker.enterState("ReactContext.onHostPause()")
bridgelessReactStateTracker.enterState("ReactContext.onHostPause()")
it.onHostPause()
}
LifecycleState.RESUMED -> {
stateTracker.enterState("ReactContext.onHostPause()")
bridgelessReactStateTracker.enterState("ReactContext.onHostPause()")
it.onHostPause()
}
else -> {
@@ -69,13 +71,13 @@ internal class ReactLifecycleStateManager(private val stateTracker: ReactHostSta
currentContext?.let {
when (state) {
LifecycleState.BEFORE_RESUME -> {
stateTracker.enterState("ReactContext.onHostDestroy()")
bridgelessReactStateTracker.enterState("ReactContext.onHostDestroy()")
it.onHostDestroy()
}
LifecycleState.RESUMED -> {
stateTracker.enterState("ReactContext.onHostPause()")
bridgelessReactStateTracker.enterState("ReactContext.onHostPause()")
it.onHostPause()
stateTracker.enterState("ReactContext.onHostDestroy()")
bridgelessReactStateTracker.enterState("ReactContext.onHostDestroy()")
it.onHostDestroy()
}
else -> {
@@ -22,8 +22,6 @@ file(TO_CMAKE_PATH "${REACT_ANDROID_DIR}" REACT_ANDROID_DIR)
file(TO_CMAKE_PATH "${REACT_BUILD_DIR}" REACT_BUILD_DIR)
file(TO_CMAKE_PATH "${REACT_COMMON_DIR}" REACT_COMMON_DIR)
set(HERMES_V1_ENABLED OFF CACHE BOOL "Build with support for Hermes v1")
# If you have ccache installed, we're going to honor it.
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
@@ -124,7 +122,6 @@ add_react_common_subdir(react/nativemodule/dom)
add_react_common_subdir(react/nativemodule/featureflags)
add_react_common_subdir(react/nativemodule/microtasks)
add_react_common_subdir(react/nativemodule/idlecallbacks)
add_react_common_subdir(react/networking)
add_react_common_subdir(jserrorhandler)
add_react_common_subdir(react/runtime)
add_react_common_subdir(react/runtime/hermes)
@@ -191,7 +188,6 @@ add_library(reactnative
$<TARGET_OBJECTS:react_nativemodule_featureflags>
$<TARGET_OBJECTS:react_nativemodule_idlecallbacks>
$<TARGET_OBJECTS:react_nativemodule_microtasks>
$<TARGET_OBJECTS:react_networking>
$<TARGET_OBJECTS:react_newarchdefaults>
$<TARGET_OBJECTS:react_performance_cdpmetrics>
$<TARGET_OBJECTS:react_performance_timeline>
@@ -281,7 +277,6 @@ target_include_directories(reactnative
$<TARGET_PROPERTY:react_nativemodule_featureflags,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_nativemodule_idlecallbacks,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_nativemodule_microtasks,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_networking,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_performance_cdpmetrics,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_performance_timeline,INTERFACE_INCLUDE_DIRECTORIES>
@@ -102,7 +102,7 @@ lastResort(const char* tag, const char* msg, const char* arg = nullptr) {
}
#else
std::cerr << msg;
if (arg != nullptr) {
if (arg) {
std::cerr << ": " << arg;
}
std::cerr << std::endl;
@@ -20,6 +20,6 @@ target_include_directories(react_devsupportjni PUBLIC .)
target_link_libraries(react_devsupportjni
fbjni
jsinspector
react_networking)
jsinspector_network)
target_compile_reactnative_options(react_devsupportjni PRIVATE)

Some files were not shown because too many files have changed in this diff Show More