in packages/metro-source-map/src/generateFunctionMap.js [97:172]
function forEachMapping(
ast: BabelNode,
context: ?Context,
pushMapping: RangeMapping => void,
) {
const nameStack = [];
let tailPos = {line: 1, column: 0};
let tailName = null;
function advanceToPos(pos: {column: number, line: number}) {
if (tailPos && positionGreater(pos, tailPos)) {
const name = nameStack[0].name; // We always have at least Program
if (name !== tailName) {
pushMapping({
name,
start: {line: tailPos.line, column: tailPos.column},
});
tailName = name;
}
}
tailPos = pos;
}
function pushFrame(name: string, loc: BabelNodeSourceLocation) {
advanceToPos(loc.start);
nameStack.unshift({name, loc});
}
function popFrame() {
const top = nameStack[0];
if (top) {
const {loc} = top;
advanceToPos(loc.end);
nameStack.shift();
}
}
if (!context) {
context = {};
}
const basename = context.filename
? fsPath.basename(context.filename).replace(/\..+$/, '')
: null;
const visitor = {
enter(
path:
| NodePath<BabelNodeProgram>
| NodePath<BabelNodeFunction>
| NodePath<BabelNodeClass>,
) {
let name = getNameForPath(path);
if (basename) {
name = removeNamePrefix(name, basename);
}
pushFrame(name, nullthrows(path.node.loc));
},
exit(
path:
| NodePath<BabelNodeProgram>
| NodePath<BabelNodeFunction>
| NodePath<BabelNodeClass>,
): void {
popFrame();
},
};
traverse(ast, {
Function: visitor,
Program: visitor,
Class: visitor,
});
}