From 871cb461051859d4594451291f2948a2ab8afba0 Mon Sep 17 00:00:00 2001 From: "Alexander J. Vincent" Date: Sun, 11 Feb 2024 12:06:36 -0800 Subject: [PATCH] fix: MethodDeclarationStructure should write an asterisk isGenerator = true (#1502) --- deno/ts_morph.js | 1 + .../MethodDeclarationStructurePrinter.ts | 1 + .../base/classLikeDeclarationBaseTests.ts | 2 +- .../methodDeclarationStructurePrinterTests.ts | 105 ++++++++++++++++++ 4 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 packages/ts-morph/src/tests/structurePrinters/class/methodDeclarationStructurePrinterTests.ts diff --git a/deno/ts_morph.js b/deno/ts_morph.js index 17498ac51..bdb1990bb 100644 --- a/deno/ts_morph.js +++ b/deno/ts_morph.js @@ -7669,6 +7669,7 @@ class MethodDeclarationStructurePrinter extends NodePrinter { if (structure.decorators != null) this.factory.forDecorator().printTexts(writer, structure.decorators); this.factory.forModifierableNode().printText(writer, structure); + writer.conditionalWrite(structure.isGenerator, "*"); writer.write(name); writer.conditionalWrite(structure.hasQuestionToken, "?"); this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters); diff --git a/packages/ts-morph/src/structurePrinters/class/MethodDeclarationStructurePrinter.ts b/packages/ts-morph/src/structurePrinters/class/MethodDeclarationStructurePrinter.ts index ca3313e89..c328c8dec 100644 --- a/packages/ts-morph/src/structurePrinters/class/MethodDeclarationStructurePrinter.ts +++ b/packages/ts-morph/src/structurePrinters/class/MethodDeclarationStructurePrinter.ts @@ -84,6 +84,7 @@ export class MethodDeclarationStructurePrinter extends NodePrinter { 0, [structure], "class c {\n public static myMethod?();\n private myMethod();\n" - + " /** Test */\n @dec\n public static override async myMethod?(param): number {\n" + + " /** Test */\n @dec\n public static override async *myMethod?(param): number {\n" + " class C {\n }\n\n console.log('here');\n" + " }\n}", ); diff --git a/packages/ts-morph/src/tests/structurePrinters/class/methodDeclarationStructurePrinterTests.ts b/packages/ts-morph/src/tests/structurePrinters/class/methodDeclarationStructurePrinterTests.ts new file mode 100644 index 000000000..1364bf4b4 --- /dev/null +++ b/packages/ts-morph/src/tests/structurePrinters/class/methodDeclarationStructurePrinterTests.ts @@ -0,0 +1,105 @@ +import { nameof } from "@ts-morph/common"; +import { expect } from "chai"; +import { FormatCodeSettings, Scope } from "../../../compiler"; +import { MethodDeclarationStructurePrinter } from "../../../structurePrinters"; +import { MethodDeclarationStructure, OptionalKind } from "../../../structures"; +import { OptionalKindAndTrivia } from "../../compiler/testHelpers"; +import { getStructureFactoryAndWriter } from "../../testHelpers"; + +describe("MethodDeclarationStructurePrinter", () => { + interface Options { + formatCodeSettings?: FormatCodeSettings; + isAmbient?: boolean; + } + + function doTest(structure: OptionalKind, expectedOutput: string, options: Options = {}) { + const { writer, factory } = getStructureFactoryAndWriter(options.formatCodeSettings); + factory.forMethodDeclaration({ isAmbient: options.isAmbient || false }).printText(writer, structure); + expect(writer.toString()).to.equal(expectedOutput); + } + + describe(nameof("printText"), () => { + it("should write a method when the structure has public scope, hasQuestionToken: true, isStatic: true, isGenerator: true, and statements", () => { + const structure: OptionalKindAndTrivia> = { + decorators: [{ name: "dec" }], + docs: [{ description: "test" }], + hasOverrideKeyword: false, + hasQuestionToken: true, + isAbstract: false, + isAsync: false, + isGenerator: true, + isStatic: true, + name: "method", + overloads: [], + parameters: [{ name: "p", type: "number" }], + returnType: "IterableIterator", + scope: Scope.Public, + statements: ["yield p;"], + typeParameters: undefined, + }; + + doTest( + structure, + [ + "/** test */", + "@dec", + "public static *method?(p: number): IterableIterator {\n yield p;\n}", + ].join("\n"), + ); + }); + + it("should write a method when the structure has isAsync: true, and statements", () => { + const structure: OptionalKindAndTrivia> = { + decorators: [], + docs: [], + hasOverrideKeyword: false, + hasQuestionToken: false, + isAbstract: false, + isAsync: true, + isGenerator: false, + isStatic: false, + name: "method", + overloads: [], + parameters: [{ name: "p", type: "number" }], + returnType: "Promise", + scope: undefined, + statements: ["return Promise.resolve(p);"], + typeParameters: undefined, + }; + + doTest( + structure, + [ + "async method(p: number): Promise {\n return Promise.resolve(p);\n}", + ].join("\n"), + ); + }); + + it("should write a method when the structure has isAbstract: true", () => { + const structure: OptionalKindAndTrivia> = { + decorators: [], + docs: [], + hasOverrideKeyword: false, + hasQuestionToken: false, + isAbstract: true, + isAsync: false, + isGenerator: false, + isStatic: false, + name: "method", + overloads: [], + parameters: [{ name: "p", type: "number" }], + returnType: "number", + scope: undefined, + statements: ["return Promise.resolve(p);"], + typeParameters: undefined, + }; + + doTest( + structure, + [ + "abstract method(p: number): number;", + ].join("\n"), + ); + }); + }); +});