prettier#Parser TypeScript Examples

The following examples show how to use prettier#Parser. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: parser.ts    From prettier-plugin-jsdoc with MIT License 4 votes vote down vote up
getParser = (originalParse: Parser["parse"], parserName: string) =>
  function jsdocParser(
    text: string,
    parsersOrOptions: Parameters<Parser["parse"]>[1],
    maybeOptions?: AllOptions,
  ): AST {
    const parsers = parsersOrOptions;
    let options = (maybeOptions ?? parsersOrOptions) as AllOptions;
    const prettierParse =
      findPluginByParser(parserName, options)?.parse || originalParse;

    const ast = prettierParse(text, parsers, options) as AST;

    // jsdocParser is deprecated,this is backward compatible will be remove
    if ((options as any).jsdocParser === false) {
      return ast;
    }
    options = {
      ...options,
      printWidth: options.jsdocPrintWidth ?? options.printWidth,
    };

    const eol =
      options.endOfLine === "auto" ? detectEndOfLine(text) : options.endOfLine;
    options = { ...options, endOfLine: "lf" };

    ast.comments.forEach((comment) => {
      if (!isBlockComment(comment)) return;
      const tokenIndex = findTokenIndex(ast.tokens, comment);
      const paramsOrder = getParamsOrders(ast, tokenIndex);

      /** Issue: https://github.com/hosseinmd/prettier-plugin-jsdoc/issues/18 */
      comment.value = comment.value.replace(/^([*]+)/g, "*");

      // Create the full comment string with line ends normalized to \n
      // This means that all following code can assume \n and should only use
      // \n.
      const commentString = `/*${comment.value.replace(/\r\n?/g, "\n")}*/`;

      /**
       * Check if this comment block is a JSDoc. Based on:
       * https://github.com/jsdoc/jsdoc/blob/master/packages/jsdoc/plugins/commentsOnly.js
       */
      if (!/^\/\*\*[\s\S]+?\*\/$/.test(commentString)) return;

      const parsed = parse(commentString, {
        spacing: "preserve",
        tokenizers: [
          tagTokenizer(),
          (spec) => {
            if ([DEFAULT, DEFAULT_VALUE].includes(spec.tag)) {
              return spec;
            }

            return typeTokenizer('preserve')(spec);
          },
          nameTokenizer(),
          descriptionTokenizer('preserve')
        ]
      })[0];

      comment.value = "";

      if (!parsed) {
        // Error on commentParser
        return;
      }

      normalizeTags(parsed);
      convertCommentDescToDescTag(parsed);

      const commentContentPrintWidth = getIndentationWidth(
        comment,
        text,
        options,
      );

      let maxTagTitleLength = 0;
      let maxTagTypeLength = 0;
      let maxTagNameLength = 0;

      let tags = parsed.tags
        // Prepare tags data
        .map(({ type, optional, ...rest }) => {
          if (type) {
            /**
             * Convert optional to standard
             * https://jsdoc.app/tags-type.html#:~:text=Optional%20parameter
             */
            type = type.replace(/[=]$/, () => {
              optional = true;
              return "";
            });

            type = convertToModernType(type);
          }

          return {
            ...rest,
            type,
            optional,
          } as Spec;
        });

      // Group tags
      tags = sortTags(tags, paramsOrder, options);

      if (options.jsdocSeparateReturnsFromParam) {
        tags = tags.flatMap((tag, index) => {
          if (tag.tag === RETURNS && tags[index - 1]?.tag === PARAM) {
            return [SPACE_TAG_DATA, tag];
          }

          return [tag];
        });
      }
      if (options.jsdocAddDefaultToDescription) {
        tags = tags.map(addDefaultValueToDescription);
      }

      tags = tags
        .map(assignOptionalAndDefaultToName)
        .map(({ type, ...rest }) => {
          if (type) {
            type = formatType(type, {
              ...options,
              printWidth: commentContentPrintWidth,
            });
          }

          return {
            ...rest,
            type,
          } as Spec;
        })
        .map(({ type, name, description, tag, ...rest }) => {
          const isVerticallyAlignAbleTags =
            TAGS_VERTICALLY_ALIGN_ABLE.includes(tag);

          if (isVerticallyAlignAbleTags) {
            maxTagTitleLength = Math.max(maxTagTitleLength, tag.length);
            maxTagTypeLength = Math.max(maxTagTypeLength, type.length);
            maxTagNameLength = Math.max(maxTagNameLength, name.length);
          }

          return {
            type,
            name,
            description: description.trim(),
            tag,
            ...rest,
          };
        });

      if (options.jsdocSeparateTagGroups) {
        tags = tags.flatMap((tag, index) => {
          const prevTag = tags[index - 1];
          if (
            prevTag &&
            !prevTag.description?.includes("\n") &&
            prevTag.tag !== DESCRIPTION &&
            prevTag.tag !== SPACE_TAG_DATA.tag &&
            tag.tag !== SPACE_TAG_DATA.tag &&
            prevTag.tag !== tag.tag
          ) {
            return [SPACE_TAG_DATA, tag];
          }

          return [tag];
        });
      }

      tags
        .filter(({ description, tag }) => {
          if (!description && TAGS_DESCRIPTION_NEEDED.includes(tag)) {
            return false;
          }
          return true;
        })
        // Create final jsDoc string
        .forEach((tagData, tagIndex, finalTagsArray) => {
          comment.value += stringify(
            tagData,
            tagIndex,
            finalTagsArray,
            { ...options, printWidth: commentContentPrintWidth },
            maxTagTitleLength,
            maxTagTypeLength,
            maxTagNameLength,
          );
        });

      comment.value = comment.value.trimEnd();

      if (comment.value) {
        comment.value = addStarsToTheBeginningOfTheLines(
          comment.value,
          options,
        );
      }

      if (eol === "cr") {
        comment.value = comment.value.replace(/\n/g, "\r");
      } else if (eol === "crlf") {
        comment.value = comment.value.replace(/\n/g, "\r\n");
      }
    });

    ast.comments = ast.comments.filter(
      (comment) => !(isBlockComment(comment) && !comment.value),
    );

    return ast;
  }