refactor(compiler-cli): add file to Babel locations (#40237)

The filename of the source-span is now added to the Babel location
when setting the source-map range in the `BabelAstHost`.

Note that the filename is only added if it is different to the main file
being processed. Otherwise Babel will generate two entries in its
generated source-map.

PR Close #40237
This commit is contained in:
Pete Bacon Darwin 2020-12-29 15:20:50 +00:00 committed by atscott
parent 3158858059
commit 8ebf538c04
2 changed files with 30 additions and 6 deletions

View File

@ -14,6 +14,10 @@ import {AstFactory, BinaryOperator, LeadingComment, ObjectLiteralProperty, Sourc
* A Babel flavored implementation of the AstFactory.
*/
export class BabelAstFactory implements AstFactory<t.Statement, t.Expression> {
constructor(
/** The absolute path to the source file being compiled. */
private sourceUrl: string) {}
attachComments(statement: t.Statement, leadingComments: LeadingComment[]): void {
// We must process the comments in reverse because `t.addComment()` will add new ones in front.
for (let i = leadingComments.length - 1; i >= 0; i--) {
@ -138,9 +142,11 @@ export class BabelAstFactory implements AstFactory<t.Statement, t.Expression> {
if (sourceMapRange === null) {
return node;
}
// Note that the linker only works on a single file at a time, so there is no need to track the
// filename. Babel will just use the current filename in the source-map.
node.loc = {
// Add in the filename so that we can map to external template files.
// Note that Babel gets confused if you specify a filename when it is the original source
// file. This happens when the template is inline, in which case just use `undefined`.
filename: sourceMapRange.url !== this.sourceUrl ? sourceMapRange.url : undefined,
start: {
line: sourceMapRange.start.line + 1, // lines are 1-based in Babel.
column: sourceMapRange.start.column,
@ -149,7 +155,7 @@ export class BabelAstFactory implements AstFactory<t.Statement, t.Expression> {
line: sourceMapRange.end.line + 1, // lines are 1-based in Babel.
column: sourceMapRange.end.column,
},
};
} as any; // Needed because the Babel typings for `loc` don't include `filename`.
node.start = sourceMapRange.start.offset;
node.end = sourceMapRange.end.offset;

View File

@ -14,7 +14,7 @@ import {BabelAstFactory} from '../../src/ast/babel_ast_factory';
describe('BabelAstFactory', () => {
let factory: BabelAstFactory;
beforeEach(() => factory = new BabelAstFactory());
beforeEach(() => factory = new BabelAstFactory('/original.ts'));
describe('attachComments()', () => {
it('should add the comments to the given statement', () => {
@ -367,16 +367,34 @@ describe('BabelAstFactory', () => {
start: {line: 0, column: 1, offset: 1},
end: {line: 2, column: 3, offset: 15},
content: '-****\n*****\n****',
url: 'original.ts'
url: 'other.ts'
});
// Lines are 1-based in Babel.
expect(expr.loc).toEqual({
filename: 'other.ts',
start: {line: 1, column: 1},
end: {line: 3, column: 3},
});
} as any); // The typings for `loc` do not include `filename`.
expect(expr.start).toEqual(1);
expect(expr.end).toEqual(15);
});
it('should use undefined if the url is the same as the one passed to the constructor', () => {
const expr = expression.ast`42`;
factory.setSourceMapRange(expr, {
start: {line: 0, column: 1, offset: 1},
end: {line: 2, column: 3, offset: 15},
content: '-****\n*****\n****',
url: '/original.ts'
});
// Lines are 1-based in Babel.
expect(expr.loc).toEqual({
filename: undefined,
start: {line: 1, column: 1},
end: {line: 3, column: 3},
} as any); // The typings for `loc` do not include `filename`.
});
});
});