Skip to content

Commit

Permalink
fix(prettier-plugin-jsdoc): add support for Prettier v3
Browse files Browse the repository at this point in the history
  • Loading branch information
homer0 committed Jul 16, 2023
1 parent 36d97d3 commit e70f6ed
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 97 deletions.
33 changes: 19 additions & 14 deletions src/fns/formatTagsTypes.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const R = require('ramda');
const { hasValidProperty } = require('./utils');
const { hasValidProperty, composeWithPromise } = require('./utils');
const { formatTSTypes } = require('./formatTSTypes');
const { formatStringLiterals } = require('./formatStringLiterals');
const { formatArrays } = require('./formatArrays');
const { formatObjects } = require('./formatObjects');
const { formatTypeAsCode } = require('./formatTypeAsCode');
const { get, provider } = require('./app');
const { reduceWithPromise } = require('./utils');

/**
* @typedef {import('../types').PJPTypesOptions} PJPTypesOptions
Expand All @@ -28,7 +29,7 @@ const { get, provider } = require('./app');
* @param {PJPTypesOptions} options The options that tell the function which formatters
* should be included and which don't.
* @param {number} column The column where the comment will be rendered.
* @returns {TypeFormatter}
* @returns {Promise<TypeFormatter>}
*/
const getTypeFormatter = (options, column) => {
const fns = [];
Expand All @@ -51,7 +52,7 @@ const getTypeFormatter = (options, column) => {
}
}

return fns.length ? R.compose(...fns.reverse()) : R.identity;
return fns.length ? get(composeWithPromise)(...fns.reverse()) : R.identity;
};

/**
Expand All @@ -61,14 +62,14 @@ const getTypeFormatter = (options, column) => {
* @callback FormatTagTypeFn
* @param {TypeFormatter} formatter The formatter function for the tag.
* @param {CommentTag} tag The tag which type will be formatted.
* @returns {CommentTag}
* @returns {Promise<CommentTag>}
*/

/**
* @type {FormatTagTypeFn}
*/
const formatTagType = R.curry((formatter, tag) =>
R.compose((type) => ({ ...tag, type }), formatter, R.prop('type'))(tag),
get(composeWithPromise)((type) => ({ ...tag, type }), formatter, R.prop('type'))(tag),
);

/**
Expand All @@ -80,20 +81,24 @@ const formatTagType = R.curry((formatter, tag) =>
* @param {number} column The column where the comment will be rendered. This
* is necessary for some transformations that can
* involve Prettier itself.
* @returns {CommentTag[]}
* @returns {Promise<CommentTag[]>}
*/

/**
* @type {FormatTagsTypes}
*/
const formatTagsTypes = R.curry((tags, options, column) =>
R.map(
R.when(
get(hasValidProperty)('type'),
get(formatTagType)(get(getTypeFormatter)(options, column)),
),
)(tags),
);
const formatTagsTypes = R.curry(async (tags, options, column) => {
const hasValidPropertyFn = get(hasValidProperty)('type');
const getTypeFormatterFn = get(getTypeFormatter)(options, column);
const formatTagTypeFn = get(formatTagType)(getTypeFormatterFn);
return get(reduceWithPromise)(tags, async (tag) => {
if (hasValidPropertyFn(tag)) {
return formatTagTypeFn(tag);
}

return tag;
});
});

module.exports.formatTagsTypes = formatTagsTypes;
module.exports.getTypeFormatter = getTypeFormatter;
Expand Down
19 changes: 10 additions & 9 deletions src/fns/formatTypeAsCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,28 @@ const COMMENT_PADDING_LENGTH = 3;
* @param {PrettierOptions} options The options sent to the plugin.
* @param {number} column The column where the comment will be rendered.
* @param {string} tag The type will be formatted.
* @returns {string}
* @returns {Promise<string>}
*/

/**
* @type {FormatPrettyTypeFn}
*/
const formatPrettyType = R.curry((options, column, type) => {
const formatPrettyType = R.curry(async (options, column, type) => {
let result;
try {
const printWidth = options.printWidth - column - COMMENT_PADDING_LENGTH;
const useType = type.replace(/\*/g, 'any');
const prefix = 'type complex = ';
const newType = format(`${prefix}${useType}`, {
const newType = await format(`${prefix}${useType}`, {
...options,
printWidth,
parser: 'typescript',
})
.substr(prefix.length)
.trim()
.replace(/;$/, '');
result = newType;
});
if (newType) {
result = newType.substr(prefix.length).trim().replace(/;$/, '');
} else {
result = type;
}
} catch (ignore) {
result = type;
}
Expand All @@ -62,7 +63,7 @@ const formatPrettyType = R.curry((options, column, type) => {
* @param {number} column The column where comment will be rendered. This is
* necessary in order to calculate the available space
* that Prettier can use.
* @returns {CommentTag}
* @returns {Promise<CommentTag>}
*/

/**
Expand Down
10 changes: 6 additions & 4 deletions src/fns/getLanguages.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ const { get, provider } = require('./app');
/**
* Generates the list of languages the plugin supports.
*
* @returns {PrettierSupportLanguage[]}
* @returns {Promise<PrettierSupportLanguage[]>}
*/
const getLanguages = () =>
R.filter(
const getLanguages = async () => {
const { languages } = await prettier.getSupportInfo();
return R.filter(
R.propSatisfies(R.includes(R.__, get(getSupportedLanguages)()), 'name'),
prettier.getSupportInfo().languages,
languages,
);
};

module.exports.getLanguages = getLanguages;
module.exports.provider = provider('getLanguages', module.exports);
86 changes: 46 additions & 40 deletions src/fns/getParsers.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const babelParser = require('prettier/plugins/babel');
const flowParser = require('prettier/plugins/flow');
const tsParser = require('prettier/plugins/typescript');
const R = require('ramda');
const { parse: commentParser } = require('comment-parser');
const babelParser = require('prettier/parser-babel');
const flowParser = require('prettier/parser-flow');
const tsParser = require('prettier/parser-typescript');
const { isMatch } = require('./utils');
const { isMatch, composeWithPromise, reduceWithPromise } = require('./utils');
const { formatDescription } = require('./formatDescription');
const { formatTags } = require('./formatTags');
const { formatTagsTypes } = require('./formatTagsTypes');
Expand Down Expand Up @@ -166,18 +166,21 @@ const shouldIgnoreComment = R.curry((options, info) =>
/**
* @type {ProcessCommentsFn}
*/
const processComments = R.curry((options, nodes, formatterFn, processorFn) =>
R.compose(
R.forEach(
R.compose(
R.ifElse(shouldIgnoreComment(options), R.identity, processorFn),
formatterFn,
get(generateCommentData),
),
),
R.filter(R.allPass([get(isComment), get(matchesBlock)])),
)(nodes),
);
const processComments = R.curry(async (options, nodes, formatterFn, processorFn) => {
const useNodes = nodes.filter(R.allPass([get(isComment), get(matchesBlock)]));
const shouldIgnoreFn = shouldIgnoreComment(options);
const generateCommentDataFn = get(generateCommentData);
return get(reduceWithPromise)(useNodes, async (node) => {
const info = generateCommentDataFn(node);
const formatted = await formatterFn(info);
const shouldIgnore = await shouldIgnoreFn(formatted);
if (shouldIgnore) {
return formatted;
}

return processorFn(formatted);
});
});

/**
* Runs all the formatting functions that require the context of a comment block, not only
Expand Down Expand Up @@ -207,14 +210,14 @@ const formatCommentBlock = R.curry((options, info) =>
* @callback FormatCommentTagsFn
* @param {PrettierOptions} options The options sent to the plugin.
* @param {ParsingInformation} info The parsed information of the comment.
* @returns {ParsingInformation}
* @returns {Promise<ParsingInformation>}
*/

/**
* @type {FormatCommentTagsFn}
*/
const formatCommentTags = R.curry((options, info) =>
R.compose(
get(composeWithPromise)(
R.assocPath(['block', 'tags'], R.__, info),
get(formatTagsTypes)(R.__, options, info.column),
get(formatTags)(R.__, options),
Expand All @@ -238,7 +241,7 @@ const formatCommentTags = R.curry((options, info) =>
* @type {PrepareCommentTagsFn}
*/
const prepareCommentTags = R.curry((options, info) =>
R.compose(
get(composeWithPromise)(
R.assocPath(['block', 'tags'], R.__, info),
get(prepareTags)(R.__, options, info.column),
R.path(['block', 'tags']),
Expand Down Expand Up @@ -285,29 +288,32 @@ const getRenderer = (options) => {
* tells the plugin that it's being extended.
* @returns {PrettierParseFn}
*/
const createParser = (originalParser, checkExtendOption) => (text, parsers, options) => {
const ast = originalParser(text, parsers, options);
if (
options &&
options.jsdocPluginEnabled &&
(!checkExtendOption || !options.jsdocPluginExtended)
) {
const formatter = R.compose(
get(prepareCommentTags)(options),
get(formatCommentTags)(options),
get(formatCommentBlock)(options),
);
const renderer = getRenderer(options);
if (ast.comments && ast.comments.length) {
get(processComments)(options, ast.comments, formatter, (info) => {
const { comment, column, block } = info;
comment.value = renderer(column, block);
});
const createParser =
(originalParser, checkExtendOption) => async (text, parsers, options) => {
const ast = originalParser(text, parsers, options);
if (
options &&
options.jsdocPluginEnabled &&
(!checkExtendOption || !options.jsdocPluginExtended)
) {
const formatter = get(composeWithPromise)(
get(prepareCommentTags)(options),
get(formatCommentTags)(options),
get(formatCommentBlock)(options),
);
const renderer = getRenderer(options);
if (ast.comments && ast.comments.length) {
await get(processComments)(options, ast.comments, formatter, (info) => {
const { comment, column, block } = info;
const value = renderer(column, block);
comment.value = value;
return info;
});
}
}
}

return ast;
};
return ast;
};

/**
* Extends an existing parser using one generated by {@link createParser}.
Expand Down
6 changes: 3 additions & 3 deletions src/fns/getPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ const { get, provider } = require('./app');
* parsers should check for the option that tells
* the plugin that it's being extended, thus, the
* original package shouldn't do anything.
* @returns {Plugin}
* @returns {Promise<Plugin>}
*/
const getPlugin = (checkExtendOption) => ({
languages: get(getLanguages)(),
const getPlugin = async (checkExtendOption) => ({
languages: await get(getLanguages)(),
options: get(getOptions)(),
defaultOptions: get(getDefaultOptions)(),
parsers: get(getParsers)(checkExtendOption),
Expand Down
43 changes: 21 additions & 22 deletions src/fns/prepareExampleTag.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { format } = require('prettier');
const R = require('ramda');
const { isTag, prefixLines, splitLinesAndClean } = require('./utils');
const { isTag, prefixLines, splitLinesAndClean, reduceWithPromise } = require('./utils');
const { get, provider } = require('./app');

/**
Expand All @@ -24,9 +24,9 @@ const COMMENT_PADDING_LENGTH = 3;
* formatter.
* @param {number} column The column where the comment will be rendered.
* @param {string} example The example code.
* @returns {string}
* @returns {Promise<string>}
*/
const formatExample = (options, column, example) => {
const formatExample = async (options, column, example) => {
let code;
let indent;
try {
Expand All @@ -36,7 +36,7 @@ const formatExample = (options, column, example) => {
printWidth -= options.tabWidth;
}

code = format(example, {
code = await format(example, {
...options,
printWidth,
});
Expand All @@ -60,22 +60,20 @@ const formatExample = (options, column, example) => {
* formatter.
* @param {number} column The column where the comment will be rendered.
* @param {string} example The example code.
* @returns {CommentTagExample[]}
* @returns {Promise<CommentTagExample[]>}
*/
const splitExamples = (options, column, example) => {
const useSplitLinesAndClean = get(splitLinesAndClean);
return R.compose(
R.map(
R.compose(
([caption, code]) => ({
caption,
code: get(formatExample)(options, column, code),
}),
useSplitLinesAndClean(/<\s*\/\s*caption\s*>/i),
),
),
useSplitLinesAndClean(/<\s*caption\s*>/i),
)(example);
const splitExamples = async (options, column, example) => {
const splitLinesAndCleanFn = get(splitLinesAndClean);
const splitEndFn = splitLinesAndCleanFn(/<\s*\/\s*caption\s*>/i);
const splitted = splitLinesAndCleanFn(/<\s*caption\s*>/i)(example);
const formatExampleFn = get(formatExample);
return get(reduceWithPromise)(splitted, async (item) => {
const [caption, code] = splitEndFn(item);
return {
caption,
code: await formatExampleFn(options, column, code),
};
});
};

/**
Expand All @@ -93,12 +91,13 @@ const splitExamples = (options, column, example) => {
/**
* @type {FormatExampleTagFn}
*/
const formatExampleTag = R.curry((options, column, tag) => {
const formatExampleTag = R.curry(async (options, column, tag) => {
let examples;
if (tag.description.match(/<\s*caption\s*>/i)) {
examples = get(splitExamples)(options, column, tag.description);
examples = await get(splitExamples)(options, column, tag.description);
} else if (tag.description.trim()) {
examples = [{ code: get(formatExample)(options, column, tag.description) }];
const code = await get(formatExample)(options, column, tag.description);
examples = [{ code }];
} else {
examples = [];
}
Expand Down

0 comments on commit e70f6ed

Please sign in to comment.