Files
react-native/local-cli/bundle/output/unbundle/util.js
David Aurelio 58ba7fc075 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
2017-04-28 12:35:23 -07:00

125 lines
3.4 KiB
JavaScript

/**
* Copyright (c) 2016-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';
const invariant = require('fbjs/lib/invariant');
import type {IndexMap, MappingsMap, SourceMap} from '../../../../packager/src/lib/SourceMap';
import type {ModuleGroups, ModuleTransportLike} from '../../types.flow';
const newline = /\r\n?|\n|\u2028|\u2029/g;
// fastest implementation
const countLines = (string: string) => (string.match(newline) || []).length + 1;
function lineToLineSourceMap(source: string, filename: string = ''): MappingsMap {
// The first line mapping in our package is the base64vlq code for zeros (A).
const firstLine = 'AAAA;';
// Most other lines in our mappings are all zeros (for module, column etc)
// except for the lineno mapping: curLineno - prevLineno = 1; Which is C.
const line = 'AACA;';
return {
file: filename,
mappings: firstLine + Array(countLines(source)).join(line),
sources: [filename],
names: [],
version: 3,
};
}
const wrapperEnd = wrappedCode => wrappedCode.indexOf('{') + 1;
const Section =
(line: number, column: number, map: SourceMap) =>
({map, offset: {line, column}});
type CombineSourceMapsOptions = {
moduleGroups?: ModuleGroups,
modules: Array<ModuleTransportLike>,
withCustomOffsets?: boolean,
};
function combineSourceMaps({
moduleGroups,
modules,
withCustomOffsets,
}: CombineSourceMapsOptions): IndexMap {
const offsets = [];
const sections = [];
const sourceMap: IndexMap = withCustomOffsets
? {sections, version: 3, x_facebook_offsets: offsets}
: {sections, version: 3};
let line = 0;
modules.forEach(moduleTransport => {
const {code, id, name} = moduleTransport;
let column = 0;
let hasOffset = false;
let group;
let groupLines = 0;
let {map} = moduleTransport;
if (withCustomOffsets) {
if (moduleGroups && moduleGroups.modulesInGroups.has(id)) {
// this is a module appended to another module
return;
}
group = moduleGroups && moduleGroups.groups.get(id);
if (group && moduleGroups) {
const {modulesById} = moduleGroups;
const otherModules: Array<ModuleTransportLike> =
Array.from(group || [])
.map(moduleId => modulesById.get(moduleId))
.filter(Boolean); // needed to appease flow
otherModules.forEach(m => {
groupLines += countLines(m.code);
});
map = combineSourceMaps({
modules: [moduleTransport].concat(otherModules),
});
}
hasOffset = id != null;
column = wrapperEnd(code);
}
invariant(
!Array.isArray(map),
'Random Access Bundle source maps cannot be built from raw mappings',
);
sections.push(Section(line, column, map || lineToLineSourceMap(code, name)));
if (hasOffset) {
offsets[id] = line;
for (const moduleId of group || []) {
offsets[moduleId] = line;
}
}
line += countLines(code) + groupLines;
});
return sourceMap;
}
const joinModules =
(modules: Array<*>): string =>
modules.map(m => m.code).join('\n');
module.exports = {
countLines,
lineToLineSourceMap,
combineSourceMaps,
joinModules,
};