mirror of https://github.com/status-im/metro.git
packager: get rid of type `any` in ResolutionRequest
Summary: One of my changeset broke the "ModuleGraph" code without warning earlier because we are using `any`, that equivalent to having no typing at all. This changeset fixes the types so that `ResolutionRequest` is exactly what it actually is: a class usable for any `Module`-looking class, including the normal one, and the "ModuleGraph" one used for Buck builds. That way, the ModuleGraph's `Module` is typechecked against `Moduleish`. Concretely this change mostly migrates the `Module` to its generic parameter counterpart `TModule` inside `ResolutionRequest`. Reviewed By: kentaromiura Differential Revision: D4826256 fbshipit-source-id: fcd7ca08ac6c35e4e9ca983e2aab260e352bcb4e
This commit is contained in:
parent
fc8c5130be
commit
c1a2a5e942
|
@ -322,12 +322,12 @@ class Bundler {
|
|||
moduleSystemDeps?: Array<Module>,
|
||||
onProgress?: () => void,
|
||||
platform?: ?string,
|
||||
resolutionResponse?: ResolutionResponse,
|
||||
resolutionResponse?: ResolutionResponse<Module>,
|
||||
runBeforeMainModule?: boolean,
|
||||
runModule?: boolean,
|
||||
unbundle?: boolean,
|
||||
}) {
|
||||
const onResolutionResponse = (response: ResolutionResponse) => {
|
||||
const onResolutionResponse = (response: ResolutionResponse<Module>) => {
|
||||
/* $FlowFixMe: looks like ResolutionResponse is monkey-patched
|
||||
* with `getModuleId`. */
|
||||
bundle.setMainModuleId(response.getModuleId(getMainModule(response)));
|
||||
|
@ -342,7 +342,7 @@ class Bundler {
|
|||
const finalizeBundle = ({bundle: finalBundle, transformedModules, response, modulesByName}: {
|
||||
bundle: Bundle,
|
||||
transformedModules: Array<{module: Module, transformed: ModuleTransport}>,
|
||||
response: ResolutionResponse,
|
||||
response: ResolutionResponse<Module>,
|
||||
modulesByName: {[name: string]: Module},
|
||||
}) =>
|
||||
this._resolverPromise.then(resolver => Promise.all(
|
||||
|
|
|
@ -44,6 +44,10 @@ module.exports = class Module {
|
|||
isHaste() {
|
||||
return this.hasteID.then(Boolean);
|
||||
}
|
||||
|
||||
hash() {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
};
|
||||
|
||||
function getName(path) {
|
||||
|
|
|
@ -101,7 +101,7 @@ class Resolver {
|
|||
transformOptions: TransformOptions,
|
||||
onProgress?: ?(finishedModules: number, totalModules: number) => mixed,
|
||||
getModuleId: mixed,
|
||||
): Promise<ResolutionResponse> {
|
||||
): Promise<ResolutionResponse<Module>> {
|
||||
const {platform, recursive = true} = options;
|
||||
return this._depGraph.getDependencies({
|
||||
entryPath,
|
||||
|
@ -151,7 +151,7 @@ class Resolver {
|
|||
}
|
||||
|
||||
resolveRequires(
|
||||
resolutionResponse: ResolutionResponse,
|
||||
resolutionResponse: ResolutionResponse<Module>,
|
||||
module: Module,
|
||||
code: string,
|
||||
dependencyOffsets: Array<number> = [],
|
||||
|
@ -195,7 +195,7 @@ class Resolver {
|
|||
dev = true,
|
||||
minify = false,
|
||||
}: {
|
||||
resolutionResponse: ResolutionResponse,
|
||||
resolutionResponse: ResolutionResponse<Module>,
|
||||
module: Module,
|
||||
name: string,
|
||||
map: SourceMap,
|
||||
|
|
|
@ -309,7 +309,7 @@ class Server {
|
|||
getDependencies(options: {
|
||||
entryFile: string,
|
||||
platform: ?string,
|
||||
}): Promise<ResolutionResponse> {
|
||||
}): Promise<ResolutionResponse<Module>> {
|
||||
return Promise.resolve().then(() => {
|
||||
if (!options.platform) {
|
||||
options.platform = getPlatformExtension(options.entryFile);
|
||||
|
|
|
@ -23,8 +23,6 @@ const getAssetDataFromName = require('../lib/getAssetDataFromName');
|
|||
|
||||
import type {HasteFS} from '../types';
|
||||
import type DependencyGraphHelpers from './DependencyGraphHelpers';
|
||||
import type Module from '../Module';
|
||||
import type ModuleCache from '../ModuleCache';
|
||||
import type ResolutionResponse from './ResolutionResponse';
|
||||
|
||||
type DirExistsFn = (filePath: string) => boolean;
|
||||
|
@ -37,14 +35,31 @@ export type ModuleMap = {
|
|||
getPackage(name: string, platform: string, supportsNativePlatform: boolean): ?string,
|
||||
};
|
||||
|
||||
type Options = {
|
||||
type Packageish = {
|
||||
redirectRequire(toModuleName: string): string | false,
|
||||
getMain(): string,
|
||||
+root: string,
|
||||
};
|
||||
|
||||
type Moduleish = {
|
||||
+path: string,
|
||||
getPackage(): ?Packageish,
|
||||
hash(): string,
|
||||
};
|
||||
|
||||
type ModuleishCache<TModule, TPackage> = {
|
||||
getPackage(name: string, platform?: string, supportsNativePlatform?: boolean): TPackage,
|
||||
getModule(path: string): TModule,
|
||||
getAssetModule(path: string): TModule,
|
||||
};
|
||||
|
||||
type Options<TModule, TPackage> = {
|
||||
dirExists: DirExistsFn,
|
||||
entryPath: string,
|
||||
extraNodeModules: ?Object,
|
||||
hasteFS: HasteFS,
|
||||
helpers: DependencyGraphHelpers,
|
||||
// TODO(cpojer): Remove 'any' type. This is used for ModuleGraph/node-haste
|
||||
moduleCache: ModuleCache | any,
|
||||
moduleCache: ModuleishCache<TModule, TPackage>,
|
||||
moduleMap: ModuleMap,
|
||||
platform: string,
|
||||
platforms: Set<string>,
|
||||
|
@ -67,14 +82,14 @@ function tryResolveSync<T>(action: () => T, secondaryAction: () => T): T {
|
|||
}
|
||||
}
|
||||
|
||||
class ResolutionRequest {
|
||||
class ResolutionRequest<TModule: Moduleish, TPackage: Packageish> {
|
||||
_dirExists: DirExistsFn;
|
||||
_entryPath: string;
|
||||
_extraNodeModules: ?Object;
|
||||
_hasteFS: HasteFS;
|
||||
_helpers: DependencyGraphHelpers;
|
||||
_immediateResolutionCache: {[key: string]: Module};
|
||||
_moduleCache: ModuleCache;
|
||||
_immediateResolutionCache: {[key: string]: TModule};
|
||||
_moduleCache: ModuleishCache<TModule, TPackage>;
|
||||
_moduleMap: ModuleMap;
|
||||
_platform: string;
|
||||
_platforms: Set<string>;
|
||||
|
@ -92,7 +107,7 @@ class ResolutionRequest {
|
|||
platform,
|
||||
platforms,
|
||||
preferNativePlatform,
|
||||
}: Options) {
|
||||
}: Options<TModule, TPackage>) {
|
||||
this._dirExists = dirExists;
|
||||
this._entryPath = entryPath;
|
||||
this._extraNodeModules = extraNodeModules;
|
||||
|
@ -115,8 +130,7 @@ class ResolutionRequest {
|
|||
});
|
||||
}
|
||||
|
||||
// TODO(cpojer): Remove 'any' type. This is used for ModuleGraph/node-haste
|
||||
resolveDependency(fromModule: Module | any, toModuleName: string): Module {
|
||||
resolveDependency(fromModule: TModule, toModuleName: string): TModule {
|
||||
const resHash = resolutionHash(fromModule.path, toModuleName);
|
||||
|
||||
const immediateResolution = this._immediateResolutionCache[resHash];
|
||||
|
@ -141,7 +155,10 @@ class ResolutionRequest {
|
|||
return cacheResult(this._resolveNodeDependency(fromModule, toModuleName));
|
||||
}
|
||||
|
||||
resolveModuleDependencies(module: Module, dependencyNames: Array<string>): [Array<string>, Array<Module>] {
|
||||
resolveModuleDependencies(
|
||||
module: TModule,
|
||||
dependencyNames: Array<string>,
|
||||
): [Array<string>, Array<TModule>] {
|
||||
const dependencies = dependencyNames.map(name => this.resolveDependency(module, name));
|
||||
return [dependencyNames, dependencies];
|
||||
}
|
||||
|
@ -152,7 +169,7 @@ class ResolutionRequest {
|
|||
onProgress,
|
||||
recursive = true,
|
||||
}: {
|
||||
response: ResolutionResponse,
|
||||
response: ResolutionResponse<TModule>,
|
||||
transformOptions: Object,
|
||||
onProgress?: ?(finishedModules: number, totalModules: number) => mixed,
|
||||
recursive: boolean,
|
||||
|
@ -250,13 +267,14 @@ class ResolutionRequest {
|
|||
});
|
||||
}
|
||||
|
||||
_resolveHasteDependency(fromModule: Module, toModuleName: string): Module {
|
||||
_resolveHasteDependency(fromModule: TModule, toModuleName: string): TModule {
|
||||
toModuleName = normalizePath(toModuleName);
|
||||
|
||||
const pck = fromModule.getPackage();
|
||||
let realModuleName;
|
||||
if (pck) {
|
||||
realModuleName = pck.redirectRequire(toModuleName);
|
||||
/* $FlowFixMe: redirectRequire can actually return `false` for exclusions */
|
||||
realModuleName = (pck.redirectRequire(toModuleName): string);
|
||||
} else {
|
||||
realModuleName = toModuleName;
|
||||
}
|
||||
|
@ -308,7 +326,7 @@ class ResolutionRequest {
|
|||
);
|
||||
}
|
||||
|
||||
_redirectRequire(fromModule: Module, modulePath: string): string | false {
|
||||
_redirectRequire(fromModule: TModule, modulePath: string): string | false {
|
||||
const pck = fromModule.getPackage();
|
||||
if (pck) {
|
||||
return pck.redirectRequire(modulePath);
|
||||
|
@ -316,7 +334,7 @@ class ResolutionRequest {
|
|||
return modulePath;
|
||||
}
|
||||
|
||||
_resolveFileOrDir(fromModule: Module, toModuleName: string): Module {
|
||||
_resolveFileOrDir(fromModule: TModule, toModuleName: string): TModule {
|
||||
const potentialModulePath = isAbsolutePath(toModuleName) ?
|
||||
resolveWindowsPath(toModuleName) :
|
||||
path.join(path.dirname(fromModule.path), toModuleName);
|
||||
|
@ -336,7 +354,7 @@ class ResolutionRequest {
|
|||
);
|
||||
}
|
||||
|
||||
_resolveNodeDependency(fromModule: Module, toModuleName: string): Module {
|
||||
_resolveNodeDependency(fromModule: TModule, toModuleName: string): TModule {
|
||||
if (isRelativeImport(toModuleName) || isAbsolutePath(toModuleName)) {
|
||||
return this._resolveFileOrDir(fromModule, toModuleName);
|
||||
}
|
||||
|
@ -408,7 +426,7 @@ class ResolutionRequest {
|
|||
* This is written as a separate function because "try..catch" blocks cause
|
||||
* the entire surrounding function to be deoptimized.
|
||||
*/
|
||||
_tryResolveNodeDep(searchPath: string, fromModule: Module, toModuleName: string): ?Module {
|
||||
_tryResolveNodeDep(searchPath: string, fromModule: TModule, toModuleName: string): ?TModule {
|
||||
try {
|
||||
return tryResolveSync(
|
||||
() => this._loadAsFile(searchPath, fromModule, toModuleName),
|
||||
|
@ -422,7 +440,7 @@ class ResolutionRequest {
|
|||
}
|
||||
}
|
||||
|
||||
_loadAsFile(potentialModulePath: string, fromModule: Module, toModule: string): Module {
|
||||
_loadAsFile(potentialModulePath: string, fromModule: TModule, toModule: string): TModule {
|
||||
if (this._helpers.isAssetFile(potentialModulePath)) {
|
||||
let dirname = path.dirname(potentialModulePath);
|
||||
if (!this._dirExists(dirname)) {
|
||||
|
@ -480,7 +498,7 @@ class ResolutionRequest {
|
|||
return this._moduleCache.getModule(file);
|
||||
}
|
||||
|
||||
_loadAsDir(potentialDirPath: string, fromModule: Module, toModule: string): Module {
|
||||
_loadAsDir(potentialDirPath: string, fromModule: TModule, toModule: string): TModule {
|
||||
if (!this._dirExists(potentialDirPath)) {
|
||||
throw new UnableToResolveError(
|
||||
fromModule,
|
||||
|
|
|
@ -16,10 +16,10 @@ import type Module from '../Module';
|
|||
|
||||
const NO_OPTIONS = {};
|
||||
|
||||
class ResolutionResponse {
|
||||
class ResolutionResponse<TModule: {hash(): string}> {
|
||||
|
||||
transformOptions: TransformOptions;
|
||||
dependencies: Array<Module>;
|
||||
dependencies: Array<TModule>;
|
||||
mainModuleId: ?(number | string);
|
||||
mocks: mixed;
|
||||
numPrependedDependencies: number;
|
||||
|
@ -29,7 +29,7 @@ class ResolutionResponse {
|
|||
|
||||
_mappings: {};
|
||||
_finalized: boolean;
|
||||
_mainModule: ?Module;
|
||||
_mainModule: ?TModule;
|
||||
|
||||
constructor({transformOptions}: {transformOptions: TransformOptions}) {
|
||||
this.transformOptions = transformOptions;
|
||||
|
@ -42,10 +42,10 @@ class ResolutionResponse {
|
|||
}
|
||||
|
||||
copy(properties: {
|
||||
dependencies?: Array<Module>,
|
||||
dependencies?: Array<TModule>,
|
||||
mainModuleId?: number,
|
||||
mocks?: mixed,
|
||||
}): ResolutionResponse {
|
||||
}): ResolutionResponse<TModule> {
|
||||
const {
|
||||
dependencies = this.dependencies,
|
||||
mainModuleId = this.mainModuleId,
|
||||
|
@ -80,7 +80,7 @@ class ResolutionResponse {
|
|||
}
|
||||
}
|
||||
|
||||
finalize(): ResolutionResponse {
|
||||
finalize(): ResolutionResponse<TModule> {
|
||||
/* $FlowFixMe: _mainModule is not initialized in the constructor. */
|
||||
return this._mainModule.getName().then(id => {
|
||||
this.mainModuleId = id;
|
||||
|
@ -89,7 +89,7 @@ class ResolutionResponse {
|
|||
});
|
||||
}
|
||||
|
||||
pushDependency(module: Module) {
|
||||
pushDependency(module: TModule) {
|
||||
this._assertNotFinalized();
|
||||
if (this.dependencies.length === 0) {
|
||||
this._mainModule = module;
|
||||
|
@ -98,7 +98,7 @@ class ResolutionResponse {
|
|||
this.dependencies.push(module);
|
||||
}
|
||||
|
||||
prependDependency(module: Module) {
|
||||
prependDependency(module: TModule) {
|
||||
this._assertNotFinalized();
|
||||
this.dependencies.unshift(module);
|
||||
this.numPrependedDependencies += 1;
|
||||
|
@ -122,7 +122,7 @@ class ResolutionResponse {
|
|||
this.mocks = mocks;
|
||||
}
|
||||
|
||||
getResolvedDependencyPairs(module: Module) {
|
||||
getResolvedDependencyPairs(module: TModule) {
|
||||
this._assertFinalized();
|
||||
return this._mappings[module.hash()];
|
||||
}
|
||||
|
|
|
@ -226,7 +226,8 @@ class Module {
|
|||
if (hasteImpl !== undefined) {
|
||||
const {enforceHasteNameMatches} = hasteImpl;
|
||||
if (enforceHasteNameMatches) {
|
||||
/* $FlowFixMe: this rely on the above if being executed, that is fragile. Rework the algo. */
|
||||
/* $FlowFixMe: this rely on the above if being executed, that is fragile.
|
||||
* Rework the algo. */
|
||||
enforceHasteNameMatches(this.path, this._hasteNameCache.hasteName);
|
||||
}
|
||||
this._hasteNameCache = {hasteName: hasteImpl.getHasteName(this.path)};
|
||||
|
|
|
@ -114,7 +114,7 @@ class ModuleCache {
|
|||
return this._moduleCache[filePath];
|
||||
}
|
||||
|
||||
getPackage(filePath: string) {
|
||||
getPackage(filePath: string): Package {
|
||||
if (!this._packageCache[filePath]) {
|
||||
this._packageCache[filePath] = new Package({
|
||||
file: filePath,
|
||||
|
|
|
@ -44,7 +44,7 @@ class Package {
|
|||
this._content = null;
|
||||
}
|
||||
|
||||
getMain() {
|
||||
getMain(): string {
|
||||
const json = this.read();
|
||||
var replacements = getReplacements(json);
|
||||
if (typeof replacements === 'string') {
|
||||
|
|
|
@ -211,7 +211,7 @@ class DependencyGraph extends EventEmitter {
|
|||
transformOptions: TransformOptions,
|
||||
onProgress?: ?(finishedModules: number, totalModules: number) => mixed,
|
||||
recursive: boolean,
|
||||
}): Promise<ResolutionResponse> {
|
||||
}): Promise<ResolutionResponse<Module>> {
|
||||
platform = this._getRequestPlatform(entryPath, platform);
|
||||
const absPath = this._getAbsolutePath(entryPath);
|
||||
const dirExists = filePath => {
|
||||
|
|
Loading…
Reference in New Issue