125 lines
3.2 KiB
JavaScript
125 lines
3.2 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';
|
|
|
|
import type {ModuleGroups, ModuleTransportLike, SourceMap} 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 = ''): SourceMap {
|
|
// 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): SourceMap {
|
|
let offsets;
|
|
const sections = [];
|
|
const sourceMap: Object = {
|
|
file: '',
|
|
sections,
|
|
version: 3,
|
|
};
|
|
|
|
|
|
if (withCustomOffsets) {
|
|
offsets = sourceMap.x_facebook_offsets = [];
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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,
|
|
};
|