diff --git a/packager/react-packager/src/Bundler/Bundle.js b/packager/react-packager/src/Bundler/Bundle.js index 7bce385e2..37b6f5e67 100644 --- a/packager/react-packager/src/Bundler/Bundle.js +++ b/packager/react-packager/src/Bundler/Bundle.js @@ -18,6 +18,7 @@ const _ = require('lodash'); const base64VLQ = require('./base64-vlq'); const crypto = require('crypto'); +import type {SourceMap, CombinedSourceMap, MixedSourceMap} from '../lib/SourceMap'; import type {GetSourceOptions, FinalizeOptions} from './BundleBase'; const SOURCEMAPPING_URL = '\n\/\/# sourceMappingURL='; @@ -53,14 +54,18 @@ class Bundle extends BundleBase { } addModule( + /** + * $FlowFixMe: this code is inherently incorrect, because it modifies the + * signature of the base class function "addModule". That means callsites + * using an instance typed as the base class would be broken. This must be + * refactored. + */ resolver: {wrapModule: (options: any) => Promise<{code: any, map: any}>}, resolutionResponse: mixed, module: mixed, + /* $FlowFixMe: erroneous change of signature. */ moduleTransport: ModuleTransport, - /* $FlowFixMe: this code is inherently incorrect, because it modifies the - * signature of the base class function "addModule", originally returning - * a number. That means callsites using an instance typed as the base class - * would be broken. This must be refactored. */ + /* $FlowFixMe: erroneous change of signature. */ ): Promise { const index = super.addModule(moduleTransport); return resolver.wrapModule({ @@ -170,7 +175,7 @@ class Bundle extends BundleBase { * that makes use of of the `sections` field to combine sourcemaps by adding * an offset. This is supported only by Chrome for now. */ - _getCombinedSourceMaps(options) { + _getCombinedSourceMaps(options): CombinedSourceMap { const result = { version: 3, file: this._getSourceMapFile(), @@ -186,6 +191,7 @@ class Bundle extends BundleBase { } if (options.excludeSource) { + /* $FlowFixMe: assume the map is not empty if we got here. */ if (map.sourcesContent && map.sourcesContent.length) { map = Object.assign({}, map, {sourcesContent: []}); } @@ -193,6 +199,7 @@ class Bundle extends BundleBase { result.sections.push({ offset: { line: line, column: 0 }, + /* $FlowFixMe: assume the map is not empty if we got here. */ map: map, }); line += module.code.split('\n').length; @@ -201,7 +208,7 @@ class Bundle extends BundleBase { return result; } - getSourceMap(options: {excludeSource?: boolean}) { + getSourceMap(options: {excludeSource?: boolean}): MixedSourceMap { super.assertFinalized(); if (this._shouldCombineSourceMaps) { @@ -336,11 +343,12 @@ class Bundle extends BundleBase { BundleBase.fromJSON(bundle, json); + /* $FlowFixMe: this modifies BundleBase#fromJSON() signature. */ return bundle; } } -function generateSourceMapForVirtualModule(module) { +function generateSourceMapForVirtualModule(module): SourceMap { // All lines map 1-to-1 let mappings = 'AAAA;'; @@ -379,6 +387,7 @@ function * filter(iterator, predicate) { function * subtree(moduleTransport: ModuleTransport, moduleTransportsByPath, seen = new Set()) { seen.add(moduleTransport.id); + /* $FlowFixMe: there may not be a `meta` object */ for (const [, {path}] of moduleTransport.meta.dependencyPairs || []) { const dependency = moduleTransportsByPath.get(path); if (dependency && !seen.has(dependency.id)) { @@ -420,6 +429,7 @@ function createGroups(ramGroups: Array, lazyModules) { return [ root.id, // `subtree` yields the IDs of all transitive dependencies of a module + /* $FlowFixMe: assumes the module is always in the Map */ new Set(subtree(byPath.get(root.sourcePath), byPath)), ]; }) diff --git a/packager/react-packager/src/Bundler/index.js b/packager/react-packager/src/Bundler/index.js index 6e4b37954..4165edcd9 100644 --- a/packager/react-packager/src/Bundler/index.js +++ b/packager/react-packager/src/Bundler/index.js @@ -329,7 +329,7 @@ class Bundler { }; const finalizeBundle = ({bundle: finalBundle, transformedModules, response, modulesByName}: { bundle: Bundle, - transformedModules: Array<{module: Module, transformed: {}}>, + transformedModules: Array<{module: Module, transformed: ModuleTransport}>, response: ResolutionResponse, modulesByName: {[name: string]: Module}, }) => diff --git a/packager/react-packager/src/lib/ModuleTransport.js b/packager/react-packager/src/lib/ModuleTransport.js index e5718e2dc..51a778029 100644 --- a/packager/react-packager/src/lib/ModuleTransport.js +++ b/packager/react-packager/src/lib/ModuleTransport.js @@ -5,30 +5,64 @@ * 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'; -function ModuleTransport(data) { - this.name = data.name; +import type {SourceMap} from './SourceMap'; - assertExists(data, 'id'); - this.id = data.id; +type Metadata = { + dependencyPairs?: Array<[mixed, {path: string}]>, + preloaded?: boolean, +}; - assertExists(data, 'code'); - this.code = data.code; +class ModuleTransport { - assertExists(data, 'sourceCode'); - this.sourceCode = data.sourceCode; + name: string; + id: string | number; + code: string; + sourceCode: string; + sourcePath: string; + virtual: ?boolean; + meta: ?Metadata; + polyfill: ?boolean; + map: ?SourceMap; - assertExists(data, 'sourcePath'); - this.sourcePath = data.sourcePath; + constructor(data: { + name: string, + id: string | number, + code: string, + sourceCode: string, + sourcePath: string, + virtual?: ?boolean, + meta?: ?Metadata, + polyfill?: ?boolean, + map?: ?SourceMap, + }) { + this.name = data.name; - this.virtual = data.virtual; - this.meta = data.meta; - this.polyfill = data.polyfill; - this.map = data.map; + assertExists(data, 'id'); + this.id = data.id; + + assertExists(data, 'code'); + this.code = data.code; + + assertExists(data, 'sourceCode'); + this.sourceCode = data.sourceCode; + + assertExists(data, 'sourcePath'); + this.sourcePath = data.sourcePath; + + this.virtual = data.virtual; + this.meta = data.meta; + this.polyfill = data.polyfill; + this.map = data.map; + + Object.freeze(this); + } - Object.freeze(this); } module.exports = ModuleTransport; diff --git a/packager/react-packager/src/lib/SourceMap.js b/packager/react-packager/src/lib/SourceMap.js new file mode 100644 index 000000000..2f427f87c --- /dev/null +++ b/packager/react-packager/src/lib/SourceMap.js @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * 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'; + +type SourceMapBase = { + version: number, + file: string, +}; + +export type SourceMap = SourceMapBase & { + sources: Array, + names: Array, + mappings: string, + sourcesContent: Array, +}; + +export type CombinedSourceMap = SourceMapBase & { + sections: Array<{ + offset: {line: number, column: number}, + map: SourceMap, + }>, +}; + +export type MixedSourceMap = SourceMap | CombinedSourceMap;