From f755db1e72af75685fbb997d2ef1fe346e8092ee Mon Sep 17 00:00:00 2001 From: Hossein Mohammadi Date: Thu, 25 Feb 2021 21:25:11 +0330 Subject: [PATCH] feat: add jsdocSingleLineComment to options issue: https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/93 --- README.md | 3 ++- src/descriptionFormatter.ts | 4 +-- src/index.ts | 21 +++++++++++++--- src/parser.ts | 11 +++++--- src/stringify.ts | 4 +-- src/types.ts | 8 ++++-- src/utils.ts | 12 ++++++--- tests/__snapshots__/main.test.ts.snap | 23 +++++++++++++++++ tests/dottedNames.test.ts | 6 ++--- tests/exampleTag.test.ts | 6 ++--- tests/files.test.ts | 11 +++----- tests/jsdocParserDisable.test.ts | 6 ++--- tests/main.test.ts | 36 ++++++++++++++++++++++++--- tests/modern.test.ts | 6 ++--- tests/objectProperty.test.ts | 6 ++--- tests/paragraph.test.ts | 6 ++--- tests/react.test.ts | 6 ++--- tests/singleTag.test.ts | 6 ++--- tests/template.test.ts | 6 ++--- tests/typeScript.test.ts | 6 ++--- 20 files changed, 136 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 05397cb..e2bd703 100755 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ module.exports = { ## Ignore -To ignore prettier use `/* */` or `//` instead of /** */ +To ignore prettier use `/* */` or `//` instead of /\*\* \*/ ## Examples @@ -180,6 +180,7 @@ Description is formatting as Markdown, so you could use any features of Markdown | jsdocDescriptionTag | Boolean | false | | jsdocVerticalAlignment | Boolean | false | | jsdocKeepUnParseAbleExampleIndent | Boolean | false | +| jsdocSingleLineComment | Boolean | true | Full up to date list and description of options can be found in Prettier help. First install plugin then run Prettier with "--help" option. diff --git a/src/descriptionFormatter.ts b/src/descriptionFormatter.ts index 28789e4..4b06b5d 100644 --- a/src/descriptionFormatter.ts +++ b/src/descriptionFormatter.ts @@ -1,6 +1,6 @@ import { format } from "prettier"; import { DESCRIPTION, EXAMPLE, TODO } from "./tags"; -import { JsdocOptions } from "./types"; +import { AllOptions } from "./types"; import { capitalizer } from "./utils"; const EMPTY_LINE_SIGNATURE = "2@^5!~#sdE!_EMPTY_LINE_SIGNATURE"; @@ -48,7 +48,7 @@ interface FormatOptions { function formatDescription( tag: string, text: string, - options: JsdocOptions, + options: AllOptions, formatOptions: FormatOptions = {}, ): string { if (!text) return text; diff --git a/src/index.ts b/src/index.ts index aabb3af..96f270a 100755 --- a/src/index.ts +++ b/src/index.ts @@ -2,55 +2,70 @@ import { getParser } from "./parser"; import parserBabel from "prettier/parser-babel"; import parserFlow from "prettier/parser-flow"; import parserTypescript from "prettier/parser-typescript"; -import prettier from "prettier"; +import prettier, { SupportOption } from "prettier"; +import { JsdocOptions } from "./types"; -const options = { +const options: Record = { jsdocParser: { + name: "jsdocParser", type: "boolean", category: "jsdoc", default: true, description: "Format with jsdoc if is true", }, jsdocSpaces: { + name: "jsdocSpaces", type: "int", category: "jsdoc", default: 1, description: "How many spaces will be used to separate tag elements.", }, jsdocDescriptionWithDot: { + name: "jsdocDescriptionWithDot", type: "boolean", category: "jsdoc", default: false, description: "Should dot be inserted at the end of description", }, jsdocDescriptionTag: { + name: "jsdocDescriptionTag", type: "boolean", category: "jsdoc", default: false, description: "Should description tag be used", }, jsdocVerticalAlignment: { + name: "jsdocVerticalAlignment", type: "boolean", category: "jsdoc", default: false, description: "Should tags, types, names and description be aligned", }, jsdocKeepUnParseAbleExampleIndent: { + name: "jsdocKeepUnParseAbleExampleIndent", type: "boolean", category: "jsdoc", default: false, description: "Should unParseAble example (pseudo code or no js code) keep its indentation", }, + jsdocSingleLineComment: { + name: "jsdocSingleLineComment", + type: "boolean", + category: "jsdoc", + default: true, + description: "Should compact single line comment", + }, }; -const defaultOptions = { +const defaultOptions: JsdocOptions = { jsdocParser: true, jsdocSpaces: 1, jsdocDescriptionWithDot: false, jsdocDescriptionTag: false, jsdocVerticalAlignment: false, jsdocKeepUnParseAbleExampleIndent: false, + jsdocSingleLineComment: true, }; const languages = prettier diff --git a/src/parser.ts b/src/parser.ts index c57e48e..05cccb0 100755 --- a/src/parser.ts +++ b/src/parser.ts @@ -17,7 +17,7 @@ import { TAGS_TYPELESS, TAGS_VERTICALLY_ALIGN_ABLE, } from "./roles"; -import { AST, JsdocOptions, PrettierComment, Token } from "./types"; +import { AST, AllOptions, PrettierComment, Token } from "./types"; import { stringify } from "./stringify"; import { Parser } from "prettier"; import { SPACE_TAG_DATA } from "./tags"; @@ -27,7 +27,7 @@ export const getParser = (parser: Parser["parse"]) => function jsdocParser( text: string, parsers: Parameters[1], - options: JsdocOptions, + options: AllOptions, ): AST { const ast = parser(text, parsers, options) as AST; @@ -201,7 +201,10 @@ export const getParser = (parser: Parser["parse"]) => comment.value = comment.value.trimEnd(); if (comment.value) { - comment.value = addStarsToTheBeginningOfTheLines(comment.value); + comment.value = addStarsToTheBeginningOfTheLines( + comment.value, + options, + ); } if (eol === "cr") { @@ -225,7 +228,7 @@ function isBlockComment(comment: PrettierComment): boolean { function getIndentationWidth( comment: PrettierComment, text: string, - options: JsdocOptions, + options: AllOptions, ): number { const line = text.split(/\r\n?|\n/g)[comment.loc.start.line - 1]; diff --git a/src/stringify.ts b/src/stringify.ts index a58e4da..127101a 100755 --- a/src/stringify.ts +++ b/src/stringify.ts @@ -7,13 +7,13 @@ import { TAGS_PEV_FORMATE_DESCRIPTION, TAGS_VERTICALLY_ALIGN_ABLE, } from "./roles"; -import { JsdocOptions } from "./types"; +import { AllOptions } from "./types"; const stringify = ( { name, description, type, tag }: Spec, tagIndex: number, finalTagsArray: Spec[], - options: JsdocOptions, + options: AllOptions, maxTagTitleLength: number, maxTagTypeNameLength: number, maxTagNameLength: number, diff --git a/src/types.ts b/src/types.ts index 9695498..ee05412 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,13 +1,17 @@ import { ParserOptions } from "prettier"; -export type JsdocOptions = { +export interface JsdocOptions { jsdocSpaces: number; jsdocDescriptionWithDot: boolean; jsdocDescriptionTag: boolean; jsdocVerticalAlignment: boolean; jsdocKeepUnParseAbleExampleIndent: boolean; jsdocParser: boolean; -} & ParserOptions; + /** default is true */ + jsdocSingleLineComment: boolean; +} + +export interface AllOptions extends ParserOptions, JsdocOptions {} type LocationDetails = { line: number; column: number }; type Location = { start: LocationDetails; end: LocationDetails }; diff --git a/src/utils.ts b/src/utils.ts index 92be3cf..eca1a71 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,5 @@ import { format, Options } from "prettier"; -import { Token } from "./types"; +import { AllOptions, Token } from "./types"; import BSearch from "binary-search-bounds"; function convertToModernType(oldType: string): string { @@ -118,8 +118,14 @@ function formatType(type: string, options?: Options): string { } } -function addStarsToTheBeginningOfTheLines(comment: string): string { - if (numberOfAStringInString(comment.trim(), "\n") === 0) { +function addStarsToTheBeginningOfTheLines( + comment: string, + options: AllOptions, +): string { + if ( + options.jsdocSingleLineComment && + numberOfAStringInString(comment.trim(), "\n") === 0 + ) { return `* ${comment.trim()} `; } diff --git a/tests/__snapshots__/main.test.ts.snap b/tests/__snapshots__/main.test.ts.snap index 31609b3..23afacb 100644 --- a/tests/__snapshots__/main.test.ts.snap +++ b/tests/__snapshots__/main.test.ts.snap @@ -162,6 +162,29 @@ exports[`Should convert to single line if necessary 3`] = ` " `; +exports[`Should convert to single multiLine 1`] = ` +"/** + * Single line description + */ +" +`; + +exports[`Should convert to single multiLine 2`] = ` +"/** + * Single line description + */ +" +`; + +exports[`Should convert to single multiLine 3`] = ` +"/** + * Single line description + * + * @returns {Boolean} Always true + */ +" +`; + exports[`Should format jsDoc default values 1`] = ` "/** * @param {String} [arg1=\\"defaultTest\\"] Foo. Default is \`\\"defaultTest\\"\` diff --git a/tests/dottedNames.test.ts b/tests/dottedNames.test.ts index 428821f..460ee74 100644 --- a/tests/dottedNames.test.ts +++ b/tests/dottedNames.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], parser: "babel", jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("dotted names function param", () => { diff --git a/tests/exampleTag.test.ts b/tests/exampleTag.test.ts index 15cfd2c..d283eb1 100755 --- a/tests/exampleTag.test.ts +++ b/tests/exampleTag.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { parser: "babel", plugins: ["."], jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("Example javascript code", () => { diff --git a/tests/files.test.ts b/tests/files.test.ts index 46f2a63..868a8ff 100644 --- a/tests/files.test.ts +++ b/tests/files.test.ts @@ -1,14 +1,11 @@ import prettier from "prettier"; import { readFileSync } from "fs"; import { resolve } from "path"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; require("jest-specific-snapshot"); -function subjectFiles( - relativePath: string, - options: Partial = {}, -) { +function subjectFiles(relativePath: string, options: Partial = {}) { const filepath = resolve(__dirname, relativePath); try { @@ -20,7 +17,7 @@ function subjectFiles( trailingComma: "all", filepath, ...options, - } as JsdocOptions); + } as AllOptions); } catch (error) { console.error(error); } @@ -35,7 +32,7 @@ function subjectFiles( */ const files: { name: string; - options?: Partial; + options?: Partial; }[] = [ { name: "typeScript.js" }, { name: "typeScript.js" }, diff --git a/tests/jsdocParserDisable.test.ts b/tests/jsdocParserDisable.test.ts index 5131128..3308ddb 100644 --- a/tests/jsdocParserDisable.test.ts +++ b/tests/jsdocParserDisable.test.ts @@ -1,14 +1,14 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], parser: "babel", jsdocParser: false, jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("template for callback", () => { diff --git a/tests/main.test.ts b/tests/main.test.ts index 79dac05..a69d03c 100755 --- a/tests/main.test.ts +++ b/tests/main.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { parser: "babel", plugins: ["."], jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("JS code should be formatted as usuall", () => { @@ -85,6 +85,36 @@ test("Should convert to single line if necessary", () => { expect(Result3).toMatchSnapshot(); }); +test("Should convert to single multiLine", () => { + const Result1 = subject(`/** single line description*/`, { + jsdocSingleLineComment: false, + }); + const Result2 = subject( + subject(`/** + * single line description + * @example + */`), + { + jsdocSingleLineComment: false, + }, + ); + + const Result3 = subject( + `/** + * single line description + * @return {Boolean} Always true + * @example + */`, + { + jsdocSingleLineComment: false, + }, + ); + + expect(Result1).toMatchSnapshot(); + expect(Result2).toMatchSnapshot(); + expect(Result3).toMatchSnapshot(); +}); + test(" undefined|null|void type", () => { const Result1 = subject(`/** * @return {undefined} diff --git a/tests/modern.test.ts b/tests/modern.test.ts index c48c88c..38ec721 100644 --- a/tests/modern.test.ts +++ b/tests/modern.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], parser: "typescript", jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("convert array to modern type", () => { diff --git a/tests/objectProperty.test.ts b/tests/objectProperty.test.ts index 69e8986..3712926 100644 --- a/tests/objectProperty.test.ts +++ b/tests/objectProperty.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { parser: "babel-flow", plugins: ["."], jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("object property", () => { diff --git a/tests/paragraph.test.ts b/tests/paragraph.test.ts index accdabf..5ebf561 100644 --- a/tests/paragraph.test.ts +++ b/tests/paragraph.test.ts @@ -1,12 +1,12 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], parser: "babel-ts", ...options, - } as JsdocOptions); + } as AllOptions); } test("description contain paragraph", () => { diff --git a/tests/react.test.ts b/tests/react.test.ts index 44b8741..3cf22e6 100755 --- a/tests/react.test.ts +++ b/tests/react.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], jsdocSpaces: 1, parser: "babel", ...options, - } as JsdocOptions); + } as AllOptions); } test("JS code should be formatted as usuall", () => { diff --git a/tests/singleTag.test.ts b/tests/singleTag.test.ts index fabcf3c..56170ef 100644 --- a/tests/singleTag.test.ts +++ b/tests/singleTag.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], jsdocSpaces: 1, parser: "babel", ...options, - } as JsdocOptions); + } as AllOptions); } test("single tag", () => { diff --git a/tests/template.test.ts b/tests/template.test.ts index 635245a..7aa83c9 100644 --- a/tests/template.test.ts +++ b/tests/template.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { plugins: ["."], jsdocSpaces: 1, parser: "babel-flow", ...options, - } as JsdocOptions); + } as AllOptions); } test("template for callback", () => { diff --git a/tests/typeScript.test.ts b/tests/typeScript.test.ts index 592bdc2..96ba1be 100644 --- a/tests/typeScript.test.ts +++ b/tests/typeScript.test.ts @@ -1,13 +1,13 @@ import prettier from "prettier"; -import { JsdocOptions } from "../src/types"; +import { AllOptions } from "../src/types"; -function subject(code: string, options: Partial = {}) { +function subject(code: string, options: Partial = {}) { return prettier.format(code, { parser: "typescript", plugins: ["."], jsdocSpaces: 1, ...options, - } as JsdocOptions); + } as AllOptions); } test("JS code should be formatted as usuall", () => {