mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Trace the import path that leads to an untranslatable file (#49480)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/49480 Changelog: [Internal] Reviewed By: huntie Differential Revision: D69752685 fbshipit-source-id: 94f70eeaec35c864c15b463f3afce929765f2c40
This commit is contained in:
committed by
Facebook GitHub Bot
parent
ebbb241bf8
commit
e4e03bd909
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
const {PACKAGES_DIR, REPO_ROOT} = require('../../consts');
|
||||
const getRequireStack = require('./resolution/getRequireStack');
|
||||
const translatedModuleTemplate = require('./templates/translatedModule.d.ts-template');
|
||||
const translateSourceFile = require('./translateSourceFile');
|
||||
const debug = require('debug')('build-types:main');
|
||||
@@ -64,14 +65,16 @@ async function buildTypes(): Promise<void> {
|
||||
ENTRY_POINTS.map(file => path.join(REPO_ROOT, file)),
|
||||
);
|
||||
const translatedFiles = new Set<string>();
|
||||
const dependencyEdges: DependencyEdges = [];
|
||||
|
||||
while (files.size > 0) {
|
||||
const dependencies = await translateSourceFiles(files);
|
||||
const dependencies = await translateSourceFiles(dependencyEdges, files);
|
||||
dependencyEdges.push(...dependencies);
|
||||
|
||||
files.forEach(file => translatedFiles.add(file));
|
||||
files.clear();
|
||||
|
||||
for (const dep of dependencies) {
|
||||
for (const [, dep] of dependencies) {
|
||||
if (
|
||||
!translatedFiles.has(dep) &&
|
||||
!IGNORE_PATTERNS.some(pattern => micromatch.isMatch(dep, pattern))
|
||||
@@ -80,13 +83,14 @@ async function buildTypes(): Promise<void> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await translateSourceFiles(files);
|
||||
}
|
||||
|
||||
type DependencyEdges = Array<[string, string]>;
|
||||
|
||||
async function translateSourceFiles(
|
||||
inputFiles: $ReadOnlySet<string>,
|
||||
): Promise<Set<string>> {
|
||||
dependencyEdges: DependencyEdges,
|
||||
inputFiles: Iterable<string>,
|
||||
): Promise<DependencyEdges> {
|
||||
const files = new Set<string>([...inputFiles]);
|
||||
|
||||
// Require common interface file (js.flow) or base implementation (.js) for
|
||||
@@ -128,7 +132,7 @@ async function translateSourceFiles(
|
||||
}
|
||||
}
|
||||
|
||||
const dependencies = new Set<string>();
|
||||
const dependencies: DependencyEdges = [];
|
||||
|
||||
await Promise.all(
|
||||
Array.from(files).map(async file => {
|
||||
@@ -140,7 +144,7 @@ async function translateSourceFiles(
|
||||
await translateSourceFile(source, file);
|
||||
|
||||
for (const dep of fileDeps) {
|
||||
dependencies.add(dep);
|
||||
dependencies.push([file, dep]);
|
||||
}
|
||||
|
||||
await fs.mkdir(path.dirname(buildPath), {recursive: true});
|
||||
@@ -153,6 +157,13 @@ async function translateSourceFiles(
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(`Failed to build ${path.relative(REPO_ROOT, file)}\n`, e);
|
||||
const requireStack = getRequireStack(dependencyEdges, file);
|
||||
if (requireStack.length > 0) {
|
||||
console.error('Chain of imports that led to this file:');
|
||||
for (const stackEntry of requireStack) {
|
||||
console.error(`- ${stackEntry}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* 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
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
type DependencyEdges = Array<[string, string]>;
|
||||
|
||||
/**
|
||||
* Given a containing dependency graph and an input file, get the first
|
||||
* complete path found when traversing dependant module edges up to the root
|
||||
* entry file. Any require cycles will be pruned.
|
||||
*
|
||||
* Time complexity: O(edges^2)
|
||||
* Space complexity: O(edges)
|
||||
*/
|
||||
function getRequireStack(edges: DependencyEdges, file: string): Array<string> {
|
||||
const requireStack = new Set<string>();
|
||||
const cycleRoots = new Set<string>();
|
||||
let currentTarget = file;
|
||||
|
||||
while (true) {
|
||||
const edge = edges.find(
|
||||
([, targetFile]) =>
|
||||
targetFile === currentTarget && !cycleRoots.has(targetFile),
|
||||
);
|
||||
|
||||
if (edge == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
const [sourceFile] = edge;
|
||||
|
||||
if (requireStack.has(sourceFile)) {
|
||||
requireStack.clear();
|
||||
cycleRoots.add(sourceFile);
|
||||
}
|
||||
|
||||
requireStack.add(sourceFile);
|
||||
currentTarget = sourceFile;
|
||||
}
|
||||
|
||||
return Array.from(requireStack);
|
||||
}
|
||||
|
||||
module.exports = getRequireStack;
|
||||
Reference in New Issue
Block a user