From 2da9c66c78f6f13927bb8823fe666ef00ba01168 Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 28 Apr 2017 12:25:44 -0700 Subject: [PATCH] Unify source map types Summary: deduplicates / unifies types for source maps across the code base Reviewed By: jeanlauliac Differential Revision: D4955924 fbshipit-source-id: 25cb71031dce835dd7d2bc1c27d6b20050906e81 --- packages/metro-bundler/src/Bundler/Bundle.js | 23 ++++++------ .../src/Bundler/source-map/Generator.js | 6 +-- .../metro-bundler/src/JSTransformer/index.js | 6 +-- .../JSTransformer/worker/constant-folding.js | 4 +- .../src/JSTransformer/worker/inline.js | 6 +-- .../src/JSTransformer/worker/worker.js | 6 +-- .../src/ModuleGraph/output/source-map.js | 30 ++------------- .../src/ModuleGraph/types.flow.js | 6 +-- packages/metro-bundler/src/Resolver/index.js | 12 +++--- .../src/Server/symbolicate/symbolicate.js | 2 +- .../metro-bundler/src/lib/ModuleTransport.js | 4 +- packages/metro-bundler/src/lib/SourceMap.js | 37 +++++++++++-------- .../metro-bundler/src/lib/TransformCache.js | 6 +-- .../src/lib/relativizeSourceMap.js | 10 +++-- .../metro-bundler/src/node-haste/Module.js | 4 +- 15 files changed, 74 insertions(+), 88 deletions(-) diff --git a/packages/metro-bundler/src/Bundler/Bundle.js b/packages/metro-bundler/src/Bundler/Bundle.js index 582853ec..45d130e7 100644 --- a/packages/metro-bundler/src/Bundler/Bundle.js +++ b/packages/metro-bundler/src/Bundler/Bundle.js @@ -20,8 +20,9 @@ const debug = require('debug')('RNP:Bundle'); const invariant = require('fbjs/lib/invariant'); const {fromRawMappings} = require('./source-map'); +const {isMappingsMap} = require('../lib/SourceMap'); -import type {SourceMap, CombinedSourceMap, MixedSourceMap} from '../lib/SourceMap'; +import type {IndexMap, MappingsMap, SourceMap} from '../lib/SourceMap'; import type {GetSourceOptions, FinalizeOptions} from './BundleBase'; export type Unbundle = { @@ -206,7 +207,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: {excludeSource?: boolean}): CombinedSourceMap { + _getCombinedSourceMaps(options: {excludeSource?: boolean}): IndexMap { const result = { version: 3, file: this._getSourceMapFile(), @@ -215,22 +216,22 @@ class Bundle extends BundleBase { let line = 0; this.getModules().forEach(module => { - let map = module.map == null || module.virtual + invariant( + !Array.isArray(module.map), + `Unexpected raw mappings for ${module.sourcePath}`, + ); + let map: SourceMap = module.map == null || module.virtual ? generateSourceMapForVirtualModule(module) : module.map; - invariant( - !Array.isArray(map), - `Unexpected raw mappings for ${module.sourcePath}`, - ); - if (options.excludeSource && 'sourcesContent' in map) { + if (options.excludeSource && isMappingsMap(map)) { map = {...map, sourcesContent: []}; } result.sections.push({ offset: {line, column: 0}, - map: (map: MixedSourceMap), + map: map, }); line += module.code.split('\n').length; }); @@ -238,7 +239,7 @@ class Bundle extends BundleBase { return result; } - getSourceMap(options: {excludeSource?: boolean}): MixedSourceMap { + getSourceMap(options: {excludeSource?: boolean}): SourceMap { this.assertFinalized(); return this._sourceMapFormat === 'indexed' @@ -314,7 +315,7 @@ class Bundle extends BundleBase { } } -function generateSourceMapForVirtualModule(module): SourceMap { +function generateSourceMapForVirtualModule(module): MappingsMap { // All lines map 1-to-1 let mappings = 'AAAA;'; diff --git a/packages/metro-bundler/src/Bundler/source-map/Generator.js b/packages/metro-bundler/src/Bundler/source-map/Generator.js index 35427c8b..cce6a1d2 100644 --- a/packages/metro-bundler/src/Bundler/source-map/Generator.js +++ b/packages/metro-bundler/src/Bundler/source-map/Generator.js @@ -13,7 +13,7 @@ const B64Builder = require('./B64Builder'); -import type {SourceMap} from 'babel-core'; +import type {MappingsMap} from '../../lib/SourceMap'; /** * Generates a source map from raw mappings. @@ -39,7 +39,7 @@ class Generator { names: IndexedSet; source: number; sources: Array; - sourcesContent: Array; + sourcesContent: Array; constructor() { this.builder = new B64Builder(); @@ -141,7 +141,7 @@ class Generator { /** * Return the source map as object. */ - toMap(file?: string): SourceMap { + toMap(file?: string): MappingsMap { return { version: 3, file, diff --git a/packages/metro-bundler/src/JSTransformer/index.js b/packages/metro-bundler/src/JSTransformer/index.js index 6cc7e56e..a084bbce 100644 --- a/packages/metro-bundler/src/JSTransformer/index.js +++ b/packages/metro-bundler/src/JSTransformer/index.js @@ -21,7 +21,7 @@ const util = require('util'); const workerFarm = require('worker-farm'); import type {Data as TransformData, Options as TransformOptions} from './worker/worker'; -import type {SourceMap} from '../lib/SourceMap'; +import type {MappingsMap} from '../lib/SourceMap'; // Avoid memory leaks caused in workers. This number seems to be a good enough number // to avoid any memory leak while not slowing down initial builds. @@ -62,8 +62,8 @@ class Transformer { minify: ( filename: string, code: string, - sourceMap: SourceMap, - ) => Promise<{code: string, map: SourceMap}>; + sourceMap: MappingsMap, + ) => Promise<{code: string, map: MappingsMap}>; constructor(transformModulePath: string, maxWorkerCount: number) { invariant(path.isAbsolute(transformModulePath), 'transform module path should be absolute'); diff --git a/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js b/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js index 3ab0b1d2..36cfbf62 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js +++ b/packages/metro-bundler/src/JSTransformer/worker/constant-folding.js @@ -13,7 +13,7 @@ const babel = require('babel-core'); -import type {Ast, SourceMap} from 'babel-core'; +import type {Ast, SourceMap as MappingsMap} from 'babel-core'; const t = babel.types; const Conditional = { @@ -73,7 +73,7 @@ const plugin = { function constantFolding(filename: string, transformResult: { ast: Ast, code?: ?string, - map: ?SourceMap, + map: ?MappingsMap, }) { return babel.transformFromAst(transformResult.ast, transformResult.code, { filename, diff --git a/packages/metro-bundler/src/JSTransformer/worker/inline.js b/packages/metro-bundler/src/JSTransformer/worker/inline.js index 9952f229..6094a7cb 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/inline.js +++ b/packages/metro-bundler/src/JSTransformer/worker/inline.js @@ -14,7 +14,7 @@ const babel = require('babel-core'); const invariant = require('fbjs/lib/invariant'); -import type {Ast, SourceMap} from 'babel-core'; +import type {Ast, SourceMap as MappingsMap} from 'babel-core'; const t = babel.types; const React = {name: 'React'}; @@ -164,12 +164,12 @@ function checkRequireArgs(args, dependencyId) { type AstResult = { ast: Ast, code: ?string, - map: ?SourceMap, + map: ?MappingsMap, }; function inline( filename: string, - transformResult: {ast?: ?Ast, code: string, map: ?SourceMap}, + transformResult: {ast?: ?Ast, code: string, map: ?MappingsMap}, options: {+dev: boolean, +platform: string}, ): AstResult { const code = transformResult.code; diff --git a/packages/metro-bundler/src/JSTransformer/worker/worker.js b/packages/metro-bundler/src/JSTransformer/worker/worker.js index a3e97820..5c437810 100644 --- a/packages/metro-bundler/src/JSTransformer/worker/worker.js +++ b/packages/metro-bundler/src/JSTransformer/worker/worker.js @@ -18,13 +18,13 @@ const invariant = require('fbjs/lib/invariant'); const minify = require('./minify'); import type {LogEntry} from '../../Logger/Types'; -import type {Ast, SourceMap} from 'babel-core'; +import type {Ast, SourceMap as MappingsMap} from 'babel-core'; export type TransformedCode = { code: string, dependencies: Array, dependencyOffsets: Array, - map?: ?SourceMap, + map?: ?MappingsMap, }; type Transformer = { @@ -32,7 +32,7 @@ type Transformer = { filename: string, sourceCode: string, options: ?{}, - ) => {ast: ?Ast, code: string, map: ?SourceMap} + ) => {ast: ?Ast, code: string, map: ?MappingsMap} }; export type TransformOptions = {| diff --git a/packages/metro-bundler/src/ModuleGraph/output/source-map.js b/packages/metro-bundler/src/ModuleGraph/output/source-map.js index bade8fec..7f45ac9c 100644 --- a/packages/metro-bundler/src/ModuleGraph/output/source-map.js +++ b/packages/metro-bundler/src/ModuleGraph/output/source-map.js @@ -10,37 +10,15 @@ */ 'use strict'; +import type {FBSourceMap, IndexMapSection, IndexMap} from '../../lib/SourceMap'; + +export type {FBSourceMap}; + type CreateIndexMapOptions = {| file?: string, sections?: Array |}; -type IndexMap = MapBase & { - sections: Array, -}; - -type IndexMapSection = { - map: IndexMap | MappingsMap, - offset: {line: number, column: number}, -}; - -type MapBase = { - // always the first entry in the source map entry object per - // https://fburl.com/source-map-spec#heading=h.qz3o9nc69um5 - version: 3, - file?: string, -}; - -type MappingsMap = MapBase & { - mappings: string, - names: Array, - sourceRoot?: string, - sources: Array, - sourcesContent?: Array, -}; - -export type SourceMap = IndexMap | MappingsMap; - exports.createIndexMap = (opts?: CreateIndexMapOptions): IndexMap => ({ version: 3, file: opts && opts.file, diff --git a/packages/metro-bundler/src/ModuleGraph/types.flow.js b/packages/metro-bundler/src/ModuleGraph/types.flow.js index fd27309e..1e250df0 100644 --- a/packages/metro-bundler/src/ModuleGraph/types.flow.js +++ b/packages/metro-bundler/src/ModuleGraph/types.flow.js @@ -10,7 +10,7 @@ */ 'use strict'; -import type {SourceMap} from './output/source-map'; +import type {MappingsMap, SourceMap} from '../lib/SourceMap'; import type {Ast} from 'babel-core'; import type {Console} from 'console'; @@ -102,7 +102,7 @@ type ResolveOptions = { export type TransformerResult = {| ast: ?Ast, code: string, - map: ?SourceMap, + map: ?MappingsMap, |}; export type Transformer = { @@ -111,7 +111,7 @@ export type Transformer = { filename: string, options: ?{}, plugins?: Array, - ) => {ast: ?Ast, code: string, map: ?SourceMap} + ) => {ast: ?Ast, code: string, map: ?MappingsMap} }; export type TransformResult = {| diff --git a/packages/metro-bundler/src/Resolver/index.js b/packages/metro-bundler/src/Resolver/index.js index 4613050b..f96ab082 100644 --- a/packages/metro-bundler/src/Resolver/index.js +++ b/packages/metro-bundler/src/Resolver/index.js @@ -18,14 +18,14 @@ const pathJoin = require('path').join; import type ResolutionResponse from '../node-haste/DependencyGraph/ResolutionResponse'; import type Module, {HasteImpl, TransformCode} from '../node-haste/Module'; -import type {SourceMap} from '../lib/SourceMap'; +import type {MappingsMap} from '../lib/SourceMap'; import type {Options as JSTransformerOptions} from '../JSTransformer/worker/worker'; import type {Reporter} from '../lib/reporting'; import type {GetTransformCacheKey} from '../lib/TransformCache'; import type {GlobalTransformCache} from '../lib/GlobalTransformCache'; -type MinifyCode = (filePath: string, code: string, map: SourceMap) => - Promise<{code: string, map: SourceMap}>; +type MinifyCode = (filePath: string, code: string, map: MappingsMap) => + Promise<{code: string, map: MappingsMap}>; type ContainsTransformerOptions = {+transformer: JSTransformerOptions} @@ -195,7 +195,7 @@ class Resolver { resolutionResponse: ResolutionResponse, module: Module, name: string, - map: SourceMap, + map: MappingsMap, code: string, meta?: { dependencyOffsets?: Array, @@ -227,8 +227,8 @@ class Resolver { } minifyModule( - {path, code, map}: {path: string, code: string, map: SourceMap}, - ): Promise<{code: string, map: SourceMap}> { + {path, code, map}: {path: string, code: string, map: MappingsMap}, + ): Promise<{code: string, map: MappingsMap}> { return this._minifyCode(path, code, map); } diff --git a/packages/metro-bundler/src/Server/symbolicate/symbolicate.js b/packages/metro-bundler/src/Server/symbolicate/symbolicate.js index 5fbb5ac1..3ea3c089 100644 --- a/packages/metro-bundler/src/Server/symbolicate/symbolicate.js +++ b/packages/metro-bundler/src/Server/symbolicate/symbolicate.js @@ -20,7 +20,7 @@ const {LazyPromise, LockingPromise} = require('./util'); const {fork} = require('child_process'); export type {SourceMap as SourceMap}; -import type {MixedSourceMap as SourceMap} from '../../lib/SourceMap'; +import type {SourceMap} from '../../lib/SourceMap'; export type Stack = Array<{file: string, lineNumber: number, column: number}>; export type Symbolicate = diff --git a/packages/metro-bundler/src/lib/ModuleTransport.js b/packages/metro-bundler/src/lib/ModuleTransport.js index 840de0e9..1c4e48bd 100644 --- a/packages/metro-bundler/src/lib/ModuleTransport.js +++ b/packages/metro-bundler/src/lib/ModuleTransport.js @@ -12,9 +12,9 @@ 'use strict'; import type {RawMapping} from '../Bundler/source-map'; -import type {MixedSourceMap} from './SourceMap'; +import type {SourceMap} from './SourceMap'; -type SourceMapOrMappings = MixedSourceMap | Array; +type SourceMapOrMappings = SourceMap | Array; type Metadata = { dependencies?: ?Array, diff --git a/packages/metro-bundler/src/lib/SourceMap.js b/packages/metro-bundler/src/lib/SourceMap.js index d356cddb..afbce101 100644 --- a/packages/metro-bundler/src/lib/SourceMap.js +++ b/packages/metro-bundler/src/lib/SourceMap.js @@ -11,23 +11,28 @@ 'use strict'; -import type {SourceMap as BabelSourceMap} from 'babel-core'; +import type {SourceMap as MappingsMap} from 'babel-core'; -export type SourceMap = BabelSourceMap; - -export type CombinedSourceMap = { - version: number, - file?: string, - sections: Array<{ - offset: {line: number, column: number}, - map: MixedSourceMap, - }>, +export type IndexMapSection = { + map: SourceMap, + offset: {line: number, column: number}, }; -type FBExtensions = {x_facebook_offsets?: Array}; +type FBExtensions = {x_facebook_offsets: Array}; -export type MixedSourceMap - = SourceMap - | CombinedSourceMap - | (SourceMap & FBExtensions) - | (CombinedSourceMap & FBExtensions); +export type {MappingsMap}; +export type IndexMap = { + file?: string, + mappings?: void, // avoids SourceMap being a disjoint union + sections: Array, + version: number, +}; + +export type SourceMap = IndexMap | MappingsMap; +export type FBSourceMap = (IndexMap & FBExtensions) | (MappingsMap & FBExtensions); + +function isMappingsMap(map: SourceMap)/*: %checks*/ { + return map.mappings !== undefined; +} + +exports.isMappingsMap = isMappingsMap; diff --git a/packages/metro-bundler/src/lib/TransformCache.js b/packages/metro-bundler/src/lib/TransformCache.js index 64d4c3dd..652ba7d9 100644 --- a/packages/metro-bundler/src/lib/TransformCache.js +++ b/packages/metro-bundler/src/lib/TransformCache.js @@ -21,7 +21,7 @@ const terminal = require('../lib/terminal'); const writeFileAtomicSync = require('write-file-atomic').sync; import type {Options as TransformOptions} from '../JSTransformer/worker/worker'; -import type {SourceMap} from './SourceMap'; +import type {MappingsMap} from './SourceMap'; import type {Reporter} from './reporting'; type CacheFilePaths = {transformedCode: string, metadata: string}; @@ -94,7 +94,7 @@ export type CachedResult = { code: string, dependencies: Array, dependencyOffsets: Array, - map?: ?SourceMap, + map?: ?MappingsMap, }; export type TransformCacheResult = {| @@ -281,7 +281,7 @@ function readMetadataFileSync( cachedSourceHash: string, dependencies: Array, dependencyOffsets: Array, - sourceMap: ?SourceMap, + sourceMap: ?MappingsMap, } { const metadataStr = fs.readFileSync(metadataFilePath, 'utf8'); let metadata; diff --git a/packages/metro-bundler/src/lib/relativizeSourceMap.js b/packages/metro-bundler/src/lib/relativizeSourceMap.js index 4b9050d8..28f35b49 100644 --- a/packages/metro-bundler/src/lib/relativizeSourceMap.js +++ b/packages/metro-bundler/src/lib/relativizeSourceMap.js @@ -13,10 +13,12 @@ const path = require('path'); -import type {MixedSourceMap} from './SourceMap'; +const {isMappingsMap} = require('./SourceMap'); -function relativizeSourceMapInternal(sourceMap: any, sourcesRoot: string) { - if (sourceMap.sections) { +import type {SourceMap} from './SourceMap'; + +function relativizeSourceMapInternal(sourceMap: SourceMap, sourcesRoot: string) { + if (!isMappingsMap(sourceMap)) { for (let i = 0; i < sourceMap.sections.length; i++) { relativizeSourceMapInternal(sourceMap.sections[i].map, sourcesRoot); } @@ -27,7 +29,7 @@ function relativizeSourceMapInternal(sourceMap: any, sourcesRoot: string) { } } -function relativizeSourceMap(sourceMap: MixedSourceMap, sourcesRoot?: string): MixedSourceMap { +function relativizeSourceMap(sourceMap: SourceMap, sourcesRoot?: string): SourceMap { if (!sourcesRoot) { return sourceMap; } diff --git a/packages/metro-bundler/src/node-haste/Module.js b/packages/metro-bundler/src/node-haste/Module.js index 2a5a7957..793fc2ea 100644 --- a/packages/metro-bundler/src/node-haste/Module.js +++ b/packages/metro-bundler/src/node-haste/Module.js @@ -24,7 +24,7 @@ const {join: joinPath, relative: relativePath, extname} = require('path'); import type {TransformedCode, Options as TransformOptions} from '../JSTransformer/worker/worker'; import type {GlobalTransformCache} from '../lib/GlobalTransformCache'; -import type {SourceMap} from '../lib/SourceMap'; +import type {MappingsMap} from '../lib/SourceMap'; import type {GetTransformCacheKey} from '../lib/TransformCache'; import type {ReadTransformProps} from '../lib/TransformCache'; import type {Reporter} from '../lib/reporting'; @@ -35,7 +35,7 @@ export type ReadResult = { +code: string, +dependencies: Array, +dependencyOffsets?: ?Array, - +map?: ?SourceMap, + +map?: ?MappingsMap, +source: string, };