• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1namespace ts {
2    describe("unittests:: TransformAPI", () => {
3        function replaceUndefinedWithVoid0(context: TransformationContext) {
4            const previousOnSubstituteNode = context.onSubstituteNode;
5            context.enableSubstitution(SyntaxKind.Identifier);
6            context.onSubstituteNode = (hint, node) => {
7                node = previousOnSubstituteNode(hint, node);
8                if (hint === EmitHint.Expression && isIdentifier(node) && node.escapedText === "undefined") {
9                    node = factory.createPartiallyEmittedExpression(
10                        addSyntheticTrailingComment(
11                            setTextRange(
12                                factory.createVoidZero(),
13                                node),
14                            SyntaxKind.MultiLineCommentTrivia, "undefined"));
15                }
16                return node;
17            };
18            return (file: SourceFile) => file;
19        }
20        function replaceNumberWith2(context: TransformationContext) {
21            function visitor(node: Node): Node {
22                if (isNumericLiteral(node)) {
23                    return factory.createNumericLiteral("2");
24                }
25                return visitEachChild(node, visitor, context);
26            }
27            return (file: SourceFile) => visitNode(file, visitor);
28        }
29
30        function replaceIdentifiersNamedOldNameWithNewName(context: TransformationContext) {
31            const previousOnSubstituteNode = context.onSubstituteNode;
32            context.enableSubstitution(SyntaxKind.Identifier);
33            context.onSubstituteNode = (hint, node) => {
34                node = previousOnSubstituteNode(hint, node);
35                if (isIdentifier(node) && node.escapedText === "oldName") {
36                    node = setTextRange(factory.createIdentifier("newName"), node);
37                }
38                return node;
39            };
40            return (file: SourceFile) => file;
41        }
42
43        function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) {
44            const visitor: Visitor = (node) => {
45                if (isIdentifier(node) && node.text === "oldName") {
46                    return factory.createIdentifier("newName");
47                }
48                return visitEachChild(node, visitor, context);
49            };
50            return (node: SourceFile) => visitNode(node, visitor);
51        }
52
53        function createTaggedTemplateLiteral(): Transformer<SourceFile> {
54            return sourceFile => factory.updateSourceFile(sourceFile, [
55                factory.createExpressionStatement(
56                    factory.createTaggedTemplateExpression(
57                        factory.createIdentifier("$tpl"),
58                        /*typeArguments*/ undefined,
59                        factory.createNoSubstitutionTemplateLiteral("foo", "foo")))
60            ]);
61        }
62
63        function transformSourceFile(sourceText: string, transformers: TransformerFactory<SourceFile>[]) {
64            const transformed = transform(createSourceFile("source.ts", sourceText, ScriptTarget.ES2015), transformers);
65            const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, {
66                onEmitNode: transformed.emitNodeWithNotification,
67                substituteNode: transformed.substituteNode
68            });
69            const result = printer.printBundle(factory.createBundle(transformed.transformed));
70            transformed.dispose();
71            return result;
72        }
73
74        function testBaseline(testName: string, test: () => string) {
75            it(testName, () => {
76                Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, test());
77            });
78        }
79
80        function testBaselineAndEvaluate(testName: string, test: () => string, onEvaluate: (exports: any) => void) {
81            describe(testName, () => {
82                let sourceText!: string;
83                before(() => {
84                    sourceText = test();
85                });
86                after(() => {
87                    sourceText = undefined!;
88                });
89                it("compare baselines", () => {
90                    Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, sourceText);
91                });
92                it("evaluate", () => {
93                    onEvaluate(evaluator.evaluateJavaScript(sourceText));
94                });
95            });
96        }
97
98        testBaseline("substitution", () => {
99            return transformSourceFile(`var a = undefined;`, [replaceUndefinedWithVoid0]);
100        });
101
102        testBaseline("types", () => {
103            return transformSourceFile(`let a: () => void`, [
104                context => file => visitNode(file, function visitor(node: Node): VisitResult<Node> {
105                    return visitEachChild(node, visitor, context);
106                })
107            ]);
108        });
109
110        testBaseline("transformDefiniteAssignmentAssertions", () => {
111            return transformSourceFile(`let a!: () => void`, [
112                context => file => visitNode(file, function visitor(node: Node): VisitResult<Node> {
113                    if (node.kind === SyntaxKind.VoidKeyword) {
114                        return factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword);
115                    }
116                    return visitEachChild(node, visitor, context);
117                })
118            ]);
119        });
120
121        testBaseline("fromTranspileModule", () => {
122            return transpileModule(`var oldName = undefined;`, {
123                transformers: {
124                    before: [replaceUndefinedWithVoid0],
125                    after: [replaceIdentifiersNamedOldNameWithNewName]
126                },
127                compilerOptions: {
128                    newLine: NewLineKind.CarriageReturnLineFeed
129                }
130            }).outputText;
131        });
132
133        testBaseline("transformTaggedTemplateLiteral", () => {
134            return transpileModule("", {
135                transformers: {
136                    before: [createTaggedTemplateLiteral],
137                },
138                compilerOptions: {
139                    target: ScriptTarget.ES5,
140                    newLine: NewLineKind.CarriageReturnLineFeed
141                }
142            }).outputText;
143        });
144
145        testBaseline("issue27854", () => {
146            return transpileModule(`oldName<{ a: string; }>\` ... \`;`, {
147                transformers: {
148                    before: [replaceIdentifiersNamedOldNameWithNewName2]
149                },
150                compilerOptions: {
151                    newLine: NewLineKind.CarriageReturnLineFeed,
152                    target: ScriptTarget.Latest
153                }
154            }).outputText;
155        });
156
157        testBaseline("issue44068", () => {
158            return transformSourceFile(`
159                const FirstVar = null;
160                const SecondVar = null;
161            `, [
162                context => file => {
163                    const firstVarName = (file.statements[0] as VariableStatement)
164                        .declarationList.declarations[0].name as Identifier;
165                    const secondVarName = (file.statements[0] as VariableStatement)
166                        .declarationList.declarations[0].name as Identifier;
167
168                    return context.factory.updateSourceFile(file, file.statements.concat([
169                        context.factory.createExpressionStatement(
170                            context.factory.createArrayLiteralExpression([firstVarName, secondVarName])
171                        ),
172                    ]));
173                }
174            ]);
175        });
176
177        testBaseline("rewrittenNamespace", () => {
178            return transpileModule(`namespace Reflect { const x = 1; }`, {
179                transformers: {
180                    before: [forceNamespaceRewrite],
181                },
182                compilerOptions: {
183                    newLine: NewLineKind.CarriageReturnLineFeed,
184                }
185            }).outputText;
186        });
187
188        testBaseline("rewrittenNamespaceFollowingClass", () => {
189            return transpileModule(`
190            class C { foo = 10; static bar = 20 }
191            namespace C { export let x = 10; }
192            `, {
193                transformers: {
194                    before: [forceNamespaceRewrite],
195                },
196                compilerOptions: {
197                    target: ScriptTarget.ESNext,
198                    newLine: NewLineKind.CarriageReturnLineFeed,
199                    useDefineForClassFields: false,
200                }
201            }).outputText;
202        });
203
204        testBaseline("transformTypesInExportDefault", () => {
205            return transpileModule(`
206            export default (foo: string) => { return 1; }
207            `, {
208                transformers: {
209                    before: [replaceNumberWith2],
210                },
211                compilerOptions: {
212                    target: ScriptTarget.ESNext,
213                    newLine: NewLineKind.CarriageReturnLineFeed,
214                }
215            }).outputText;
216        });
217
218        testBaseline("synthesizedClassAndNamespaceCombination", () => {
219            return transpileModule("", {
220                transformers: {
221                    before: [replaceWithClassAndNamespace],
222                },
223                compilerOptions: {
224                    target: ScriptTarget.ESNext,
225                    newLine: NewLineKind.CarriageReturnLineFeed,
226                }
227            }).outputText;
228
229            function replaceWithClassAndNamespace() {
230                return (sourceFile: SourceFile) => {
231                    // TODO(rbuckton): Does this need to be parented?
232                    const result = factory.updateSourceFile(
233                        sourceFile,
234                        factory.createNodeArray([
235                            factory.createClassDeclaration(/*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), // TODO: GH#18217
236                            factory.createModuleDeclaration(/*modifiers*/ undefined, factory.createIdentifier("Foo"), factory.createModuleBlock([factory.createEmptyStatement()]))
237                        ])
238                    );
239                    return result;
240                };
241            }
242        });
243
244        function forceNamespaceRewrite(context: TransformationContext) {
245            return (sourceFile: SourceFile): SourceFile => {
246                return visitNode(sourceFile);
247
248                function visitNode<T extends Node>(node: T): T {
249                    if (node.kind === SyntaxKind.ModuleBlock) {
250                        const block = node as T & ModuleBlock;
251                        const statements = factory.createNodeArray([...block.statements]);
252                        return factory.updateModuleBlock(block, statements) as typeof block;
253                    }
254                    return visitEachChild(node, visitNode, context);
255                }
256            };
257        }
258
259        testBaseline("transformAwayExportStar", () => {
260            return transpileModule("export * from './helper';", {
261                transformers: {
262                    before: [expandExportStar],
263                },
264                compilerOptions: {
265                    target: ScriptTarget.ESNext,
266                    newLine: NewLineKind.CarriageReturnLineFeed,
267                }
268            }).outputText;
269
270            function expandExportStar(context: TransformationContext) {
271                return (sourceFile: SourceFile): SourceFile => {
272                    return visitNode(sourceFile);
273
274                    function visitNode<T extends Node>(node: T): T {
275                        if (node.kind === SyntaxKind.ExportDeclaration) {
276                            const ed = node as Node as ExportDeclaration;
277                            const exports = [{ name: "x" }];
278                            const exportSpecifiers = exports.map(e => factory.createExportSpecifier(/*isTypeOnly*/ false, e.name, e.name));
279                            const exportClause = factory.createNamedExports(exportSpecifiers);
280                            const newEd = factory.updateExportDeclaration(ed, ed.modifiers, ed.isTypeOnly, exportClause, ed.moduleSpecifier, ed.assertClause);
281
282                            return newEd as Node as T;
283                        }
284                        return visitEachChild(node, visitNode, context);
285                    }
286                };
287            }
288        });
289
290        // https://github.com/Microsoft/TypeScript/issues/19618
291        testBaseline("transformAddImportStar", () => {
292            return transpileModule("", {
293                transformers: {
294                    before: [transformAddImportStar],
295                },
296                compilerOptions: {
297                    target: ScriptTarget.ES5,
298                    module: ModuleKind.System,
299                    newLine: NewLineKind.CarriageReturnLineFeed,
300                }
301            }).outputText;
302
303            function transformAddImportStar(_context: TransformationContext) {
304                return (sourceFile: SourceFile): SourceFile => {
305                    return visitNode(sourceFile);
306                };
307                function visitNode(sf: SourceFile) {
308                    // produce `import * as i0 from './comp';
309                    const importStar = factory.createImportDeclaration(
310                        /*modifiers*/ undefined,
311                        /*importClause*/ factory.createImportClause(
312                            /*isTypeOnly*/ false,
313                            /*name*/ undefined,
314                            factory.createNamespaceImport(factory.createIdentifier("i0"))
315                        ),
316                        /*moduleSpecifier*/ factory.createStringLiteral("./comp1"),
317                        /*assertClause*/ undefined);
318                    return factory.updateSourceFile(sf, [importStar]);
319                }
320            }
321        });
322
323        // https://github.com/Microsoft/TypeScript/issues/17384
324        testBaseline("transformAddDecoratedNode", () => {
325            return transpileModule("", {
326                transformers: {
327                    before: [transformAddDecoratedNode],
328                },
329                compilerOptions: {
330                    target: ScriptTarget.ES5,
331                    newLine: NewLineKind.CarriageReturnLineFeed,
332                }
333            }).outputText;
334
335            function transformAddDecoratedNode(_context: TransformationContext) {
336                return (sourceFile: SourceFile): SourceFile => {
337                    return visitNode(sourceFile);
338                };
339                function visitNode(sf: SourceFile) {
340                    // produce `class Foo { @Bar baz() {} }`;
341                    const classDecl = factory.createClassDeclaration(/*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [
342                        factory.createMethodDeclaration([factory.createDecorator(factory.createIdentifier("Bar"))], /**/ undefined, "baz", /**/ undefined, /**/ undefined, [], /**/ undefined, factory.createBlock([]))
343                    ]);
344                    return factory.updateSourceFile(sf, [classDecl]);
345                }
346            }
347        });
348
349        testBaseline("transformDeclarationFile", () => {
350            return baselineDeclarationTransform(`var oldName = undefined;`, {
351                transformers: {
352                    afterDeclarations: [replaceIdentifiersNamedOldNameWithNewName]
353                },
354                compilerOptions: {
355                    newLine: NewLineKind.CarriageReturnLineFeed,
356                    declaration: true
357                }
358            });
359        });
360
361        // https://github.com/microsoft/TypeScript/issues/33295
362        testBaseline("transformParameterProperty", () => {
363            return transpileModule("", {
364                transformers: {
365                    before: [transformAddParameterProperty],
366                },
367                compilerOptions: {
368                    target: ScriptTarget.ES5,
369                    newLine: NewLineKind.CarriageReturnLineFeed,
370                }
371            }).outputText;
372
373            function transformAddParameterProperty(_context: TransformationContext) {
374                return (sourceFile: SourceFile): SourceFile => {
375                    return visitNode(sourceFile);
376                };
377                function visitNode(sf: SourceFile) {
378                    // produce `class Foo { constructor(@Dec private x) {} }`;
379                    // The decorator is required to trigger ts.ts transformations.
380                    const classDecl = factory.createClassDeclaration([], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [
381                        factory.createConstructorDeclaration(/*modifiers*/ undefined, [
382                            factory.createParameterDeclaration([factory.createDecorator(factory.createIdentifier("Dec")), factory.createModifier(SyntaxKind.PrivateKeyword)], /*dotDotDotToken*/ undefined, "x")], factory.createBlock([]))
383                    ]);
384                    return factory.updateSourceFile(sf, [classDecl]);
385                }
386            }
387        });
388
389        function baselineDeclarationTransform(text: string, opts: TranspileOptions) {
390            const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true, { documents: [new documents.TextDocument("/.src/index.ts", text)] });
391            const host = new fakes.CompilerHost(fs, opts.compilerOptions);
392            const program = createProgram(["/.src/index.ts"], opts.compilerOptions!, host);
393            program.emit(program.getSourceFile("/.src/index.ts"), (p, s, bom) => host.writeFile(p, s, bom), /*cancellationToken*/ undefined, /*onlyDts*/ true, opts.transformers);
394            return fs.readFileSync("/.src/index.d.ts").toString();
395        }
396
397        function addSyntheticComment(nodeFilter: (node: Node) => boolean) {
398            return (context: TransformationContext) => {
399                return (sourceFile: SourceFile): SourceFile => {
400                    return visitNode(sourceFile, rootTransform, isSourceFile);
401                };
402                function rootTransform<T extends Node>(node: T): VisitResult<T> {
403                    if (nodeFilter(node)) {
404                        setEmitFlags(node, EmitFlags.NoLeadingComments);
405                        setSyntheticLeadingComments(node, [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]);
406                    }
407                    return visitEachChild(node, rootTransform, context);
408                }
409            };
410        }
411
412        // https://github.com/Microsoft/TypeScript/issues/24096
413        testBaseline("transformAddCommentToArrowReturnValue", () => {
414            return transpileModule(`const foo = () =>
415    void 0
416`, {
417                transformers: {
418                    before: [addSyntheticComment(isVoidExpression)],
419                },
420                compilerOptions: {
421                    target: ScriptTarget.ES5,
422                    newLine: NewLineKind.CarriageReturnLineFeed,
423                }
424            }).outputText;
425        });
426
427        // https://github.com/Microsoft/TypeScript/issues/17594
428        testBaseline("transformAddCommentToExportedVar", () => {
429            return transpileModule(`export const exportedDirectly = 1;
430const exportedSeparately = 2;
431export {exportedSeparately};
432`, {
433                transformers: {
434                    before: [addSyntheticComment(isVariableStatement)],
435                },
436                compilerOptions: {
437                    target: ScriptTarget.ES5,
438                    newLine: NewLineKind.CarriageReturnLineFeed,
439                }
440            }).outputText;
441        });
442
443        // https://github.com/Microsoft/TypeScript/issues/17594
444        testBaseline("transformAddCommentToImport", () => {
445            return transpileModule(`
446// Previous comment on import.
447import {Value} from 'somewhere';
448import * as X from 'somewhere';
449// Previous comment on export.
450export { /* specifier comment */ X, Y} from 'somewhere';
451export * from 'somewhere';
452export {Value};
453`, {
454                transformers: {
455                    before: [addSyntheticComment(n => isImportDeclaration(n) || isExportDeclaration(n) || isImportSpecifier(n) || isExportSpecifier(n))],
456                },
457                compilerOptions: {
458                    target: ScriptTarget.ES5,
459                    newLine: NewLineKind.CarriageReturnLineFeed,
460                }
461            }).outputText;
462        });
463
464        // https://github.com/Microsoft/TypeScript/issues/17594
465        testBaseline("transformAddCommentToProperties", () => {
466            return transpileModule(`
467// class comment.
468class Clazz {
469    // original comment 1.
470    static staticProp: number = 1;
471    // original comment 2.
472    instanceProp: number = 2;
473    // original comment 3.
474    constructor(readonly field = 1) {}
475}
476`, {
477                transformers: {
478                    before: [addSyntheticComment(n => isPropertyDeclaration(n) || isParameterPropertyDeclaration(n, n.parent) || isClassDeclaration(n) || isConstructorDeclaration(n))],
479                },
480                compilerOptions: {
481                    target: ScriptTarget.ES2015,
482                    newLine: NewLineKind.CarriageReturnLineFeed,
483                }
484            }).outputText;
485        });
486
487        testBaseline("transformAddCommentToNamespace", () => {
488            return transpileModule(`
489// namespace comment.
490namespace Foo {
491    export const x = 1;
492}
493// another comment.
494namespace Foo {
495    export const y = 1;
496}
497`, {
498                transformers: {
499                    before: [addSyntheticComment(n => isModuleDeclaration(n))],
500                },
501                compilerOptions: {
502                    target: ScriptTarget.ES2015,
503                    newLine: NewLineKind.CarriageReturnLineFeed,
504                }
505            }).outputText;
506        });
507
508        testBaseline("transformUpdateModuleMember", () => {
509            return transpileModule(`
510module MyModule {
511    const myVariable = 1;
512    function foo(param: string) {}
513}
514`, {
515                transformers: {
516                    before: [renameVariable],
517                },
518                compilerOptions: {
519                    target: ScriptTarget.ES2015,
520                    newLine: NewLineKind.CarriageReturnLineFeed,
521                }
522            }).outputText;
523
524            function renameVariable(context: TransformationContext) {
525                    return (sourceFile: SourceFile): SourceFile => {
526                        return visitNode(sourceFile, rootTransform, isSourceFile);
527                    };
528                    function rootTransform<T extends Node>(node: T): Node {
529                        if (isVariableDeclaration(node)) {
530                            return factory.updateVariableDeclaration(node, factory.createIdentifier("newName"), /*exclamationToken*/ undefined, /*type*/ undefined, node.initializer);
531                        }
532                        return visitEachChild(node, rootTransform, context);
533                    }
534            }
535        });
536
537        // https://github.com/Microsoft/TypeScript/issues/24709
538        testBaseline("issue24709", () => {
539            const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true);
540            const transformed = transform(createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ScriptTarget.ES3), [transformSourceFile]);
541            const transformedSourceFile = transformed.transformed[0];
542            transformed.dispose();
543            const host = new fakes.CompilerHost(fs);
544            host.getSourceFile = () => transformedSourceFile;
545            const program = createProgram(["source.ts"], {
546                target: ScriptTarget.ES3,
547                module: ModuleKind.None,
548                noLib: true
549            }, host);
550            program.emit(transformedSourceFile, (_p, s, b) => host.writeFile("source.js", s, b));
551            return host.readFile("source.js")!.toString();
552
553            function transformSourceFile(context: TransformationContext) {
554                const visitor: Visitor = (node) => {
555                    if (isMethodDeclaration(node)) {
556                        return factory.updateMethodDeclaration(
557                            node,
558                            node.modifiers,
559                            node.asteriskToken,
560                            factory.createIdentifier("foobar"),
561                            node.questionToken,
562                            node.typeParameters,
563                            node.parameters,
564                            node.type,
565                            node.body,
566                        );
567                    }
568                    return visitEachChild(node, visitor, context);
569                };
570                return (node: SourceFile) => visitNode(node, visitor);
571            }
572
573        });
574
575        testBaselineAndEvaluate("templateSpans", () => {
576            return transpileModule("const x = String.raw`\n\nhello`; exports.stringLength = x.trim().length;", {
577                compilerOptions: {
578                    target: ScriptTarget.ESNext,
579                    newLine: NewLineKind.CarriageReturnLineFeed,
580                },
581                transformers: {
582                    before: [transformSourceFile]
583                }
584            }).outputText;
585
586            function transformSourceFile(context: TransformationContext): Transformer<SourceFile> {
587                function visitor(node: Node): VisitResult<Node> {
588                    if (isNoSubstitutionTemplateLiteral(node)) {
589                        return factory.createNoSubstitutionTemplateLiteral(node.text, node.rawText);
590                    }
591                    else {
592                        return visitEachChild(node, visitor, context);
593                    }
594                }
595                return sourceFile => visitNode(sourceFile, visitor, isSourceFile);
596            }
597        }, exports => {
598            assert.equal(exports.stringLength, 5);
599        });
600
601        function addStaticFieldWithComment(context: TransformationContext) {
602            return (sourceFile: SourceFile): SourceFile => {
603                return visitNode(sourceFile, rootTransform, isSourceFile);
604            };
605            function rootTransform<T extends Node>(node: T): Node {
606                if (isClassLike(node)) {
607                    const newMembers = [factory.createPropertyDeclaration([factory.createModifier(SyntaxKind.StaticKeyword)], "newField", /* questionOrExclamationToken */ undefined, /* type */ undefined, factory.createStringLiteral("x"))];
608                    setSyntheticLeadingComments(newMembers[0], [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "comment", pos: -1, end: -1, hasTrailingNewLine: true }]);
609                    return isClassDeclaration(node) ?
610                        factory.updateClassDeclaration(
611                            node,
612                            node.modifiers,
613                            node.name,
614                            node.typeParameters,
615                            node.heritageClauses,
616                            newMembers) :
617                            isClassExpression(node) ?
618                        factory.updateClassExpression(
619                            node,
620                            node.modifiers,
621                            node.name,
622                            node.typeParameters,
623                            node.heritageClauses,
624                            newMembers) :
625                        factory.updateStructDeclaration(
626                            node,
627                            node.modifiers,
628                            node.name,
629                            node.typeParameters,
630                            node.heritageClauses,
631                            node.members);
632                }
633                return visitEachChild(node, rootTransform, context);
634            }
635        }
636
637        testBaseline("transformSyntheticCommentOnStaticFieldInClassDeclaration", () => {
638            return transpileModule(`
639declare const Decorator: any;
640@Decorator
641class MyClass {
642}
643`, {
644                transformers: {
645                    before: [addStaticFieldWithComment],
646                },
647                compilerOptions: {
648                    target: ScriptTarget.ES2015,
649                    newLine: NewLineKind.CarriageReturnLineFeed,
650                }
651            }).outputText;
652        });
653
654        testBaseline("transformSyntheticCommentOnStaticFieldInClassExpression", () => {
655            return transpileModule(`
656const MyClass = class {
657};
658`, {
659                transformers: {
660                    before: [addStaticFieldWithComment],
661                },
662                compilerOptions: {
663                    target: ScriptTarget.ES2015,
664                    newLine: NewLineKind.CarriageReturnLineFeed,
665                }
666            }).outputText;
667        });
668
669    });
670}
671
672