Skip to content

Commit

Permalink
fix: use Babel to strip comments and unmap line numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Jul 1, 2020
1 parent 5987889 commit 24edbbc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 38 deletions.
3 changes: 3 additions & 0 deletions packages/bundle-source/demo/circular/a.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// eslint-disable-next-line import/no-cycle
import { bar } from './b';

/**
* @type {import('./b').Bar}
*/
export const foo = 'Foo';
export default bar;
5 changes: 5 additions & 0 deletions packages/bundle-source/demo/circular/b.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// eslint-disable-next-line import/no-cycle
import { foo } from './a';

/*
* --------->
* <!-- foo as bar -->
*/
console.error('here am I');
export { foo as bar };
89 changes: 51 additions & 38 deletions packages/bundle-source/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import resolve0 from '@rollup/plugin-node-resolve';
import commonjs0 from '@rollup/plugin-commonjs';
import * as babelParser from '@agoric/babel-parser';
import babelGenerate from '@babel/generator';
import babelTraverse from '@babel/traverse';
import { makeTransform } from '@agoric/transform-eventual-send';

import { SourceMapConsumer } from 'source-map';
Expand All @@ -12,9 +13,14 @@ const DEFAULT_MODULE_FORMAT = 'nestedEvaluate';
const DEFAULT_FILE_PREFIX = '/bundled-source';
const SUPPORTED_FORMATS = ['getExport', 'nestedEvaluate'];

// eslint-disable-next-line no-useless-concat
const IMPORT_RE = new RegExp('\\b(import)' + '(\\s*(?:\\(|/[/*]))', 'g');
const HTML_COMMENT_RE = new RegExp(`(?:${'<'}!--|--${'>'})`, 'g');
const removeComments = comments => {
if (!comments) {
return;
}
// We remove all the JS comments to prevent misidentifying HTML
// comments, or import expressions.
comments.splice(0, comments.length);
};

export function tildotPlugin() {
const transformer = makeTransform(babelParser, babelGenerate);
Expand Down Expand Up @@ -73,51 +79,58 @@ export default async function bundleSource(
if (isEntry) {
entrypoint = fileName;
}
let unmappedCode = code;

// Parse the rolled-up chunk with Babel.
const ast = (babelParser.parse || babelParser)(code);

let unmapLoc;
if (
moduleFormat === 'nestedEvaluate' &&
!fileName.startsWith('_virtual/')
) {
// TODO: Should parse the generated chunk with Babel.
// We rearrange the generated chunk according to its sourcemap to move
// its source lines back to the right place, like Babel generator's
// `retainLines: true`.
unmappedCode = '';
// We rearrange the rolled-up chunk according to its sourcemap to move
// its source lines back to the right place.
// eslint-disable-next-line no-await-in-loop
const consumer = await new SourceMapConsumer(chunk.map);
const genLines = code.split('\n');
let lastLine = 1;
for (let genLine = 0; genLine < genLines.length; genLine += 1) {
const pos = consumer.originalPositionFor({
line: genLine + 1,
column: 0,
});
const { line: origLine } = pos;

const srcLine = origLine === null ? lastLine : origLine;
const priorChar = unmappedCode[unmappedCode.length - 1];
if (
srcLine === lastLine &&
!['\n', ';', '{', undefined].includes(priorChar) &&
!['}'].includes(genLines[genLine][0])
) {
unmappedCode += `;`;
let lastPos = ast.loc.start;
unmapLoc = loc => {
if (!loc) {
return;
}
while (lastLine < srcLine) {
unmappedCode += `\n`;
lastLine += 1;
for (const pos of ['start', 'end']) {
if (loc[pos]) {
const newPos = consumer.originalPositionFor(loc[pos]);
if (newPos.source !== null) {
lastPos = loc[pos];
lastPos.line = newPos.line;
lastPos.column = newPos.column;
}
loc[pos] = lastPos;
}
}
unmappedCode += genLines[genLine];
}
};
}

// Rewrite apparent import expressions so that they don't fail under SES.
// We also do apparent HTML comments.
const defangedCode = unmappedCode
.replace(IMPORT_RE, '$1notreally')
.replace(HTML_COMMENT_RE, '<->');
// console.log(`<<<<<< ${fileName}\n${defangedCode}\n>>>>>>>>`);
sourceBundle[fileName] = defangedCode;
babelTraverse(ast, {
enter(p) {
const { loc, leadingComments, trailingComments } = p.node;
// Remove all comments.
removeComments(leadingComments);
removeComments(trailingComments);
if (p.node.type.startsWith('Comment')) {
p.replaceWithMultiple([]);
return;
}
// If not a comment, and we are unmapping the source maps,
// then do it for this location.
if (unmapLoc) {
unmapLoc(loc);
}
},
});

// Now generate the sources with the new positions.
sourceBundle[fileName] = babelGenerate(ast, { retainLines: true }).code;
}

if (!entrypoint) {
Expand Down

0 comments on commit 24edbbc

Please sign in to comment.