Files
react-native/packager/src/ModuleGraph/worker/collect-dependencies.js
T
Christoph Pojer a2c84d14ce Remove react-packager indirection.
Summary:
This moves the `src` directory one level up and removes the `react-packager` folder. Personally, I always disliked this indirection. I'm reorganizing some things in RNP, so this seems to make sense.

Not sure if I forgot to update any paths. Can anyone advice if there are more places that need change?

Reviewed By: jeanlauliac

Differential Revision: D4487867

fbshipit-source-id: d63f9c79d6238300df9632d2e6a4e6a4196d5ccb
2017-02-02 05:44:15 -08:00

151 lines
3.8 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 nullthrows = require('fbjs/lib/nullthrows');
const {traverse, types} = require('babel-core');
type AST = Object;
class Replacement {
nameToIndex: Map<string, number>;
nextIndex: number;
constructor() {
this.nameToIndex = new Map();
this.nextIndex = 0;
}
isRequireCall(callee, firstArg) {
return (
callee.type === 'Identifier' && callee.name === 'require' &&
firstArg && isLiteralString(firstArg)
);
}
getIndex(stringLiteralOrTemplateLiteral) {
const name = stringLiteralOrTemplateLiteral.quasis
? stringLiteralOrTemplateLiteral.quasis[0].value.cooked
: stringLiteralOrTemplateLiteral.value;
let index = this.nameToIndex.get(name);
if (index !== undefined) {
return index;
}
index = this.nextIndex++;
this.nameToIndex.set(name, index);
return index;
}
getNames() {
return Array.from(this.nameToIndex.keys());
}
makeArgs(newId, oldId, dependencyMapIdentifier) {
const mapLookup = createMapLookup(dependencyMapIdentifier, newId);
return [mapLookup, oldId];
}
}
class ProdReplacement {
replacement: Replacement;
names: Array<string>;
constructor(names) {
this.replacement = new Replacement();
this.names = names;
}
isRequireCall(callee, firstArg) {
return (
callee.type === 'Identifier' &&
callee.name === 'require' &&
firstArg &&
firstArg.type === 'MemberExpression' &&
firstArg.property &&
firstArg.property.type === 'NumericLiteral'
);
}
getIndex(memberExpression) {
const id = memberExpression.property.value;
if (id in this.names) {
return this.replacement.getIndex({value: this.names[id]});
}
throw new Error(
`${id} is not a known module ID. Existing mappings: ${
this.names.map((n, i) => `${i} => ${n}`).join(', ')}`
);
}
getNames() {
return this.replacement.getNames();
}
makeArgs(newId, _, dependencyMapIdentifier) {
const mapLookup = createMapLookup(dependencyMapIdentifier, newId);
return [mapLookup];
}
}
function createMapLookup(dependencyMapIdentifier, propertyIdentifier) {
return types.memberExpression(
dependencyMapIdentifier,
propertyIdentifier,
true,
);
}
function collectDependencies(ast, replacement, dependencyMapIdentifier) {
const traversalState = {dependencyMapIdentifier};
traverse(ast, {
Program(path, state) {
if (!state.dependencyMapIdentifier) {
state.dependencyMapIdentifier =
path.scope.generateUidIdentifier('dependencyMap');
}
},
CallExpression(path, state) {
const node = path.node;
const arg = node.arguments[0];
if (replacement.isRequireCall(node.callee, arg)) {
const index = replacement.getIndex(arg);
node.arguments = replacement.makeArgs(
types.numericLiteral(index),
arg,
state.dependencyMapIdentifier,
);
}
},
}, null, traversalState);
return {
dependencies: replacement.getNames(),
dependencyMapName: nullthrows(traversalState.dependencyMapIdentifier).name,
};
}
function isLiteralString(node) {
return node.type === 'StringLiteral' ||
node.type === 'TemplateLiteral' && node.quasis.length === 1;
}
exports = module.exports =
(ast: AST) => collectDependencies(ast, new Replacement());
exports.forOptimization =
(ast: AST, names: Array<string>, dependencyMapName?: string) =>
collectDependencies(
ast,
new ProdReplacement(names),
dependencyMapName ? types.identifier(dependencyMapName) : undefined,
);