diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 3bd3d1b1cbb..e898f9199f7 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -1335,6 +1335,11 @@ namespace ts { setSourceMapRange(statement, moveRangePastModifiers(property)); setCommentRange(statement, property); setOriginalNode(statement, property); + // `setOriginalNode` *copies* the `emitNode` from `property`, so now both + // `statement` and `expression` have a copy of the synthesized comments. + // Drop the comments from expression to avoid printing them twice. + setSyntheticLeadingComments(expression, undefined); + setSyntheticTrailingComments(expression, undefined); statements.push(statement); } } diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 476dc6540d5..256a1db2e30 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -599,6 +599,63 @@ module MyModule { }, exports => { assert.equal(exports.stringLength, 5); }); + + function addStaticFieldWithComment(context: TransformationContext) { + return (sourceFile: SourceFile): SourceFile => { + return visitNode(sourceFile, rootTransform, isSourceFile); + }; + function rootTransform(node: T): Node { + if (isClassLike(node)) { + const newMembers = [factory.createPropertyDeclaration(/* decorators */ undefined, [factory.createModifier(SyntaxKind.StaticKeyword)], "newField", /* questionOrExclamationToken */ undefined, /* type */ undefined, factory.createStringLiteral("x"))]; + setSyntheticLeadingComments(newMembers[0], [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]); + return isClassDeclaration(node) ? + factory.updateClassDeclaration( + node, node.decorators, + /* modifierFlags */ undefined, node.name, + node.typeParameters, node.heritageClauses, + newMembers) : + factory.updateClassExpression( + node, node.decorators, + /* modifierFlags */ undefined, node.name, + node.typeParameters, node.heritageClauses, + newMembers); + } + return visitEachChild(node, rootTransform, context); + } + } + + testBaseline("transformSyntheticCommentOnStaticFieldInClassDeclaration", () => { + return transpileModule(` +declare const Decorator: any; +@Decorator +class MyClass { +} +`, { + transformers: { + before: [addStaticFieldWithComment], + }, + compilerOptions: { + target: ScriptTarget.ES2015, + newLine: NewLineKind.CarriageReturnLineFeed, + } + }).outputText; + }); + + testBaseline("transformSyntheticCommentOnStaticFieldInClassExpression", () => { + return transpileModule(` +const MyClass = class { +}; +`, { + transformers: { + before: [addStaticFieldWithComment], + }, + compilerOptions: { + target: ScriptTarget.ES2015, + newLine: NewLineKind.CarriageReturnLineFeed, + } + }).outputText; + }); + }); } diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.transformSyntheticCommentOnStaticFieldInClassDeclaration.js b/tests/baselines/reference/transformApi/transformsCorrectly.transformSyntheticCommentOnStaticFieldInClassDeclaration.js new file mode 100644 index 00000000000..df471270ae2 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.transformSyntheticCommentOnStaticFieldInClassDeclaration.js @@ -0,0 +1,13 @@ +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +let MyClass = class MyClass { +}; +/*comment*/ +MyClass.newField = "x"; +MyClass = __decorate([ + Decorator +], MyClass); diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.transformSyntheticCommentOnStaticFieldInClassExpression.js b/tests/baselines/reference/transformApi/transformsCorrectly.transformSyntheticCommentOnStaticFieldInClassExpression.js new file mode 100644 index 00000000000..e6ca9fc6ac3 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.transformSyntheticCommentOnStaticFieldInClassExpression.js @@ -0,0 +1,6 @@ +var _a; +const MyClass = (_a = class { + }, + /*comment*/ + _a.newField = "x", + _a);