RM node-haste DependencyGraph: @flow

Summary: In addition to adding flow in that file, I also had to fix `Module.js` and others to make everything compatible together.

Reviewed By: davidaurelio

Differential Revision: D4118829

fbshipit-source-id: 4f6dbc515741c38817cc4c9757e981fabb03915a
This commit is contained in:
Jean Lauliac 2016-11-04 10:42:41 -07:00 committed by Facebook Github Bot
parent dee58678c6
commit 403d4ed721
6 changed files with 111 additions and 45 deletions

View File

@ -67,21 +67,24 @@ class Cache {
return path.join(tmpdir, hash.digest('hex'));
}
get(
get<T>(
filepath: string,
field: string,
loaderCb: (filepath: string) => Promise<mixed>,
): Promise<mixed> {
loaderCb: (filepath: string) => Promise<T>,
): Promise<T> {
if (!isAbsolutePath(filepath)) {
throw new Error('Use absolute paths');
}
return this.has(filepath, field)
? this._data[filepath].data[field]
/* $FlowFixMe: this class is unsound as a whole because it uses
* untyped storage where in fact each "field" has a particular type.
* We cannot express this using Flow. */
? (this._data[filepath].data[field]: Promise<T>)
: this.set(filepath, field, loaderCb(filepath));
}
invalidate(filepath: string, field: string) {
invalidate(filepath: string, field: ?string) {
if (this.has(filepath, field)) {
if (field == null) {
delete this._data[filepath];
@ -95,16 +98,16 @@ class Cache {
return this._persistCache();
}
has(filepath: string, field: string) {
has(filepath: string, field: ?string) {
return Object.prototype.hasOwnProperty.call(this._data, filepath) &&
(field == null || Object.prototype.hasOwnProperty.call(this._data[filepath].data, field));
}
set(
set<T>(
filepath: string,
field: string,
loaderPromise: Promise<mixed>,
): Promise<mixed> {
loaderPromise: Promise<T>,
): Promise<T> {
let record = this._data[filepath];
if (!record) {
// $FlowFixMe: temporarily invalid record.

View File

@ -18,7 +18,9 @@ const isAbsolutePath = require('absolute-path');
const jsonStableStringify = require('json-stable-stringify');
const path = require('path');
import type Cache from './Cache';
import type ModuleCache from './ModuleCache';
import type FastFs from './fastfs';
export type Extractor = (sourceCode: string) => {deps: {sync: Array<string>}};
type TransformedCode = {
@ -37,23 +39,7 @@ export type TransformCode = (
dependencyOffsets?: Array<number>,
map?: string,
}>;
export type Cache = {
get<T>(
filePath: string,
key: string,
loadFunc: () => Promise<T>,
): Promise<T>,
invalidate(filePath: string): void,
};
export type Options = {cacheTransformResults?: boolean};
export type FastFs = {
readFile: (filePath: string) => Promise<string>,
closest: (innerFilePath: string, fileName: string) => string,
on: (
event: 'change',
onChange: (type: string, filePath: string, root: string) => void,
) => FastFs,
};
export type DepGraphHelpers = {isNodeModulesDir: (filePath: string) => boolean};
export type ConstructorArgs = {

View File

@ -18,14 +18,14 @@ const Polyfill = require('./Polyfill');
const path = require('path');
import type Cache from './Cache';
import type {
Cache,
DepGraphHelpers,
FastFs,
Extractor,
TransformCode,
Options as ModuleOptions,
} from './Module';
import type FastFs from './fastfs';
class ModuleCache {

View File

@ -14,10 +14,8 @@
const isAbsolutePath = require('absolute-path');
const path = require('path');
import type {
Cache,
FastFs,
} from './Module';
import type Cache from './Cache';
import type FastFs from './fastfs';
class Package {
@ -74,7 +72,7 @@ class Package {
);
}
getName() {
getName(): Promise<string> {
return this._cache.get(this.path, 'package-name', () =>
this.read().then(json => json.name)
);

View File

@ -18,11 +18,6 @@ const {EventEmitter} = require('events');
const NOT_FOUND_IN_ROOTS = 'NotFoundInRootsError';
interface Activity {
startEvent(title: string, m: mixed, opts: mixed): mixed,
endEvent(activity: mixed): void,
}
interface FileWatcher {
on(event: 'all', handler: (type: string, filePath: string, rootPath: string, fstat: fs.Stats) => void): void,
}
@ -41,16 +36,14 @@ class Fastfs extends EventEmitter {
_ignore: (filePath: string) => boolean;
_roots: Array<File>;
_fastPaths: {[filePath: string]: File};
_activity: mixed;
constructor(
name: string,
roots: Array<string>,
fileWatcher: FileWatcher,
files: Array<string>,
{ignore, activity}: {
{ignore}: {
ignore: (filePath: string) => boolean,
activity: Activity,
},
) {
super();

View File

@ -5,7 +5,10 @@
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/
'use strict';
const Cache = require('./Cache');
@ -31,6 +34,12 @@ const path = require('path');
const replacePatterns = require('./lib/replacePatterns');
const util = require('util');
import type {
TransformCode,
Options as ModuleOptions,
Extractor,
} from './Module';
const ERROR_BUILDING_DEP_GRAPH = 'DependencyGraphError';
const {
@ -41,6 +50,39 @@ const {
} = require('../Logger');
class DependencyGraph {
_opts: {
roots: Array<string>,
ignoreFilePath: (filePath: string) => boolean,
fileWatcher: FileWatcher,
assetRoots_DEPRECATED: Array<string>,
assetExts: Array<string>,
providesModuleNodeModules: mixed,
platforms: Set<mixed>,
preferNativePlatform: boolean,
extensions: Array<string>,
mocksPattern: mixed,
extractRequires: Extractor,
transformCode: TransformCode,
shouldThrowOnUnresolvedErrors: () => boolean,
enableAssetMap: boolean,
moduleOptions: ModuleOptions,
extraNodeModules: mixed,
useWatchman: boolean,
maxWorkers: number,
resetCache: boolean,
};
_cache: Cache;
_assetDependencies: mixed;
_helpers: DependencyGraphHelpers;
_fastfs: Fastfs;
_moduleCache: ModuleCache;
_hasteMap: HasteMap;
_deprecatedAssetMap: DeprecatedAssetMap;
_hasteMapError: ?Error;
_loading: ?Promise<mixed>;
constructor({
roots,
ignoreFilePath,
@ -64,6 +106,28 @@ class DependencyGraph {
useWatchman,
maxWorkers,
resetCache,
}: {
roots: Array<string>,
ignoreFilePath: (filePath: string) => boolean,
fileWatcher: FileWatcher,
assetRoots_DEPRECATED: Array<string>,
assetExts: Array<string>,
providesModuleNodeModules: mixed,
platforms: mixed,
preferNativePlatform: boolean,
cache: Cache,
extensions: Array<string>,
mocksPattern: mixed,
extractRequires: Extractor,
transformCode: TransformCode,
shouldThrowOnUnresolvedErrors: () => boolean,
enableAssetMap: boolean,
assetDependencies: mixed,
moduleOptions: ?ModuleOptions,
extraNodeModules: mixed,
useWatchman: boolean,
maxWorkers: number,
resetCache: boolean,
}) {
this._opts = {
roots,
@ -187,6 +251,7 @@ class DependencyGraph {
const error = new Error(
`Failed to build DependencyGraph: ${err.message}`
);
/* $FlowFixMe: monkey-patching */
error.type = ERROR_BUILDING_DEP_GRAPH;
error.stack = err.stack;
throw error;
@ -201,7 +266,7 @@ class DependencyGraph {
* Returns a promise with the direct dependencies the module associated to
* the given entryPath has.
*/
getShallowDependencies(entryPath, transformOptions) {
getShallowDependencies(entryPath: string, transformOptions: mixed) {
return this._moduleCache
.getModule(entryPath)
.getDependencies(transformOptions);
@ -214,7 +279,7 @@ class DependencyGraph {
/**
* Returns the module object for the given path.
*/
getModuleForPath(entryFile) {
getModuleForPath(entryFile: string) {
return this._moduleCache.getModule(entryFile);
}
@ -228,6 +293,12 @@ class DependencyGraph {
transformOptions,
onProgress,
recursive = true,
}: {
entryPath: string,
platform: string,
transformOptions: mixed,
onProgress: () => void,
recursive: boolean,
}) {
return this.load().then(() => {
platform = this._getRequestPlatform(entryPath, platform);
@ -258,11 +329,11 @@ class DependencyGraph {
});
}
matchFilesByPattern(pattern) {
matchFilesByPattern(pattern: RegExp) {
return this.load().then(() => this._fastfs.matchFilesByPattern(pattern));
}
_getRequestPlatform(entryPath, platform) {
_getRequestPlatform(entryPath: string, platform: string) {
if (platform == null) {
platform = getPlatformExtension(entryPath, this._opts.platforms);
} else if (!this._opts.platforms.has(platform)) {
@ -322,16 +393,30 @@ class DependencyGraph {
}
return this._loading;
};
/* $FlowFixMe: there is a risk this happen before we assign that
* variable in the load() function. */
this._loading = this._loading.then(resolve, resolve);
}
createPolyfill(options) {
createPolyfill(options: {file: string}) {
return this._moduleCache.createPolyfill(options);
}
getHasteMap() {
return this._hasteMap;
}
static Cache;
static Fastfs;
static FileWatcher;
static Module;
static Polyfill;
static extractRequires;
static getAssetDataFromName;
static getPlatformExtension;
static replacePatterns;
static getInverseDependencies;
}
Object.assign(DependencyGraph, {
@ -348,6 +433,7 @@ Object.assign(DependencyGraph, {
});
function NotFoundError() {
/* $FlowFixMe: monkey-patching */
Error.call(this);
Error.captureStackTrace(this, this.constructor);
var msg = util.format.apply(util, arguments);