From 8ebf538c0486e2393c22814b5c65ad5c46f6b2c8 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Tue, 29 Dec 2020 15:20:50 +0000 Subject: [PATCH] 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 --- .../linker/babel/src/ast/babel_ast_factory.ts | 12 +++++++--- .../babel/test/ast/babel_ast_factory_spec.ts | 24 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/packages/compiler-cli/linker/babel/src/ast/babel_ast_factory.ts b/packages/compiler-cli/linker/babel/src/ast/babel_ast_factory.ts index 811f8a9bac..70f4b408af 100644 --- a/packages/compiler-cli/linker/babel/src/ast/babel_ast_factory.ts +++ b/packages/compiler-cli/linker/babel/src/ast/babel_ast_factory.ts @@ -14,6 +14,10 @@ import {AstFactory, BinaryOperator, LeadingComment, ObjectLiteralProperty, Sourc * A Babel flavored implementation of the AstFactory. */ export class BabelAstFactory implements AstFactory { + 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 { 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 { 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; diff --git a/packages/compiler-cli/linker/babel/test/ast/babel_ast_factory_spec.ts b/packages/compiler-cli/linker/babel/test/ast/babel_ast_factory_spec.ts index c1f874d7f6..950eafc40c 100644 --- a/packages/compiler-cli/linker/babel/test/ast/babel_ast_factory_spec.ts +++ b/packages/compiler-cli/linker/babel/test/ast/babel_ast_factory_spec.ts @@ -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`. + }); }); });