Skip to content

Commit d01576b

Browse files
devversionalxhub
authored andcommitted
refactor(compiler-cli): properly preserve file overview comments (#54819)
This commit updates the logic for preserving file overview comments to be more reliable and less dependent on previous transforms. Previously, with the old import manager, we had a utility called `addImport` that always separated import statements and non-import statements. This meant that the non-emitted statement from Tsickle for the synthetic file-overview comments no longer lived at the beginning of the file. `addImports` tried to overcome this by adding another new non-emitted statement *before* all imports. This then was later used by the transform (or was assumed!) to attach the synthetic file overview comments if the original tsickle AST Node is no longer at the top. This logic can be improved, because the import manager shouldn't need to bother about this fileoverview non-emitted statement, and the logic for re-attaching the fileoverview comment should be local. This commit fixes this and makes it a local transform. PR Close #54819
1 parent de75fe0 commit d01576b

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

packages/compiler-cli/src/ngtsc/transform/src/transform.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ function transformIvySourceFile(
341341
sf = importManager.transformTsFile(context, sf, constants);
342342

343343
if (fileOverviewMeta !== null) {
344-
setFileOverviewComment(sf, fileOverviewMeta);
344+
sf = insertFileOverviewComment(sf, fileOverviewMeta);
345345
}
346346

347347
return sf;
@@ -382,7 +382,8 @@ function getFileOverviewComment(statements: ts.NodeArray<ts.Statement>): FileOve
382382
return null;
383383
}
384384

385-
function setFileOverviewComment(sf: ts.SourceFile, fileoverview: FileOverviewMeta): void {
385+
function insertFileOverviewComment(
386+
sf: ts.SourceFile, fileoverview: FileOverviewMeta): ts.SourceFile {
386387
const {comments, host, trailing} = fileoverview;
387388
// If host statement is no longer the first one, it means that extra statements were added at the
388389
// very beginning, so we need to relocate @fileoverview comment and cleanup the original statement
@@ -393,8 +394,17 @@ function setFileOverviewComment(sf: ts.SourceFile, fileoverview: FileOverviewMet
393394
} else {
394395
ts.setSyntheticLeadingComments(host, undefined);
395396
}
396-
ts.setSyntheticLeadingComments(sf.statements[0], comments);
397+
398+
// Note: Do not use the first statement as it may be elided at runtime.
399+
// E.g. an import declaration that is type only.
400+
const commentNode = ts.factory.createNotEmittedStatement(sf);
401+
ts.setSyntheticLeadingComments(commentNode, comments);
402+
403+
return ts.factory.updateSourceFile(
404+
sf, [commentNode, ...sf.statements], sf.isDeclarationFile, sf.referencedFiles,
405+
sf.typeReferenceDirectives, sf.hasNoDefaultLib, sf.libReferenceDirectives);
397406
}
407+
return sf;
398408
}
399409

400410
function maybeFilterDecorator(

packages/compiler-cli/test/ngtsc/ngtsc_spec.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {NgtscProgram} from '@angular/compiler-cli/src/ngtsc/program';
10+
import {CompilerOptions} from '@angular/compiler-cli/src/transformers/api';
11+
import {createCompilerHost} from '@angular/compiler-cli/src/transformers/compiler_host';
912
import {platform} from 'os';
1013
import ts from 'typescript';
1114

1215
import {ErrorCode, ngErrorCode} from '../../src/ngtsc/diagnostics';
13-
import {absoluteFrom} from '../../src/ngtsc/file_system';
16+
import {absoluteFrom, NgtscCompilerHost} from '../../src/ngtsc/file_system';
1417
import {runInEachFileSystem} from '../../src/ngtsc/file_system/testing';
1518
import {loadStandardTestFiles} from '../../src/ngtsc/testing';
1619
import {restoreTypeScriptVersionForTesting, setTypeScriptVersionForTesting} from '../../src/typescript_support';
@@ -9294,6 +9297,60 @@ function allTests(os: string) {
92949297
.toContain(
92959298
'{ i0.ɵɵtwoWayBindingSet(ctx.a, $event) || (ctx.a = $event); return $event; }');
92969299
});
9300+
9301+
describe('tsickle compatibility', () => {
9302+
it('should preserve fileoverview comments', () => {
9303+
env.write('test.ts', `
9304+
// type-only import that will be elided.
9305+
import {SimpleChanges} from '@angular/core';
9306+
9307+
export class X {
9308+
p: SimpleChanges = null!;
9309+
}
9310+
`);
9311+
9312+
const options: CompilerOptions = {
9313+
strict: true,
9314+
strictTemplates: true,
9315+
target: ts.ScriptTarget.Latest,
9316+
module: ts.ModuleKind.ESNext,
9317+
annotateForClosureCompiler: true,
9318+
};
9319+
9320+
const program = new NgtscProgram(['/test.ts'], options, createCompilerHost({options}));
9321+
const transformers = program.compiler.prepareEmit().transformers;
9322+
9323+
// Add a "fake tsickle" transform before Angular's transform.
9324+
transformers.before!.unshift(ctx => (sf: ts.SourceFile) => {
9325+
const tsickleFileOverview = ctx.factory.createNotEmittedStatement(sf);
9326+
ts.setSyntheticLeadingComments(tsickleFileOverview, [
9327+
{
9328+
kind: ts.SyntaxKind.MultiLineCommentTrivia,
9329+
text: `*
9330+
* @fileoverview Closure comment
9331+
* @supress bla1
9332+
* @supress bla2
9333+
`,
9334+
pos: -1,
9335+
end: -1,
9336+
hasTrailingNewLine: true,
9337+
},
9338+
]);
9339+
return ctx.factory.updateSourceFile(
9340+
sf, [tsickleFileOverview, ...sf.statements], sf.isDeclarationFile,
9341+
sf.referencedFiles, sf.typeReferenceDirectives, sf.hasNoDefaultLib,
9342+
sf.libReferenceDirectives);
9343+
});
9344+
9345+
const {diagnostics, emitSkipped} =
9346+
program.getTsProgram().emit(undefined, undefined, undefined, undefined, transformers);
9347+
9348+
expect(diagnostics.length).toBe(0);
9349+
expect(emitSkipped).toBe(false);
9350+
9351+
expect(env.getContents('/test.js')).toContain(`* @fileoverview Closure comment`);
9352+
});
9353+
});
92979354
});
92989355
});
92999356

0 commit comments

Comments
 (0)