Skip to content

Commit

Permalink
fix(ivy): copy top-level comments into generated factory shims (#29065)
Browse files Browse the repository at this point in the history
When ngtsc generates a .ngfactory shim, it does so based on the contents of
an original file in the program. Occasionally these original files have
comments at the top which are load-bearing (e.g. they contain jsdoc
annotations which are significant to downstream bundling tools). The
generated factory shims should preserve this comment.

This commit adds a step to the ngfactory generator to preserve the top-level
comment from the original source file.

FW-1006 #resolve
FW-1095 #resolve

PR Close #29065
  • Loading branch information
alxhub authored and AndrewKushnir committed Mar 4, 2019
1 parent 04cf4ef commit 866d500
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
15 changes: 13 additions & 2 deletions packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,25 @@ export class FactoryGenerator implements ShimGenerator {
// Grab the symbol name.
.map(decl => decl.name !.text);

let sourceText = '';

// If there is a top-level comment in the original file, copy it over at the top of the
// generated factory file. This is important for preserving any load-bearing jsdoc comments.
let comment: string = '';
if (original.statements.length > 0) {
const firstStatement = original.statements[0];
if (firstStatement.getLeadingTriviaWidth() > 0) {
comment = firstStatement.getFullText().substr(0, firstStatement.getLeadingTriviaWidth());
}
}

let sourceText = comment;
if (symbolNames.length > 0) {
// For each symbol name, generate a constant export of the corresponding NgFactory.
// This will encompass a lot of symbols which don't need factories, but that's okay
// because it won't miss any that do.
const varLines = symbolNames.map(
name => `export const ${name}NgFactory = new i0.ɵNgModuleFactory(${name});`);
sourceText = [
sourceText += [
// This might be incorrect if the current package being compiled is Angular core, but it's
// okay to leave in at type checking time. TypeScript can handle this reference via its path
// mapping, but downstream bundlers can't. If the current package is core itself, this will
Expand Down
16 changes: 16 additions & 0 deletions packages/compiler-cli/test/ngtsc/ngtsc_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,22 @@ describe('ngtsc behavioral tests', () => {
expect(emptyFactory).toContain(`export var ɵNonEmptyModule = true;`);
});

it('should copy a top-level comment into a factory stub', () => {
env.tsconfig({'allowEmptyCodegenFiles': true});

env.write('test.ts', `/** I am a top-level comment. */
import {NgModule} from '@angular/core';
@NgModule({})
export class TestModule {}
`);

env.driveMain();

const factoryContents = env.getContents('test.ngfactory.js');
expect(factoryContents).toMatch(/^\/\*\* I am a top-level comment\. \*\//);
});

it('should be able to compile an app using the factory shim', () => {
env.tsconfig({'allowEmptyCodegenFiles': true});

Expand Down

0 comments on commit 866d500

Please sign in to comment.