Skip to content

Commit

Permalink
fix(check-line-alignment): if no types are present, ensure names an…
Browse files Browse the repository at this point in the history
…d descriptions are properly aligned; fixes #894 (#909)
  • Loading branch information
TGCrystal committed Aug 30, 2022
1 parent f775de5 commit fe0e209
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 12 deletions.
73 changes: 73 additions & 0 deletions README.md
Expand Up @@ -2697,6 +2697,79 @@ const fn = ( lorem, sit ) => {};
*/
const fn2 = () => {}
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]

/**
* Function description.
*
* @param lorem Description.
* @param sit Description multi words.
* @return Return description.
*/
const fn = ( lorem, sit ) => {};

/**
* Function description.
*
* @param lorem Description.
* @param sit Description multi words.
* @returns Return description.
*/
const fn2 = ( lorem, sit ) => {};

/**
* Function description.
*
* @param a Description.
* @param b Description multi words.
* @returns Return description.
*/
const fn3 = ( a, b ) => {};
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]

/**
* Function description.
*
* @argument lorem Description.
* @return Return description.
*/
const fn = ( lorem ) => {};

/**
* Function description.
*
* @argument lorem Description.
* @returns Return description.
*/
const fn2 = ( lorem ) => {};
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]

/**
* Function description.
*
* @arg a Description.
* @returns Return description.
*/
const fn = ( a ) => {};
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]

/**
* Function description.
*
* @arg lorem Description.
* @param sit Return description.
*/
const fn = ( lorem, sit ) => {};
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]

/**
* Function description.
*
* @arg a Description.
* @argument b Second description.
* @returns Return description.
*/
const fn = ( a, b ) => {};
// "jsdoc/check-line-alignment": ["error"|"warn", "always"]
````


Expand Down
59 changes: 47 additions & 12 deletions src/alignTransform.js
Expand Up @@ -66,6 +66,35 @@ const getWidth = (tags) => {
};
};

const getTypelessInfo = (fields) => {
const hasNoTypes = fields.tags.every(({
type,
}) => {
return !type;
});
const maxNamedTagLength = Math.max(...fields.tags.map(({
tag,
name,
}) => {
return name.length === 0 ? -1 : tag.length;
}).filter((length) => {
return length !== -1;
})) + 1;
const maxUnnamedTagLength = Math.max(...fields.tags.map(({
tag,
name,
}) => {
return name.length === 0 ? tag.length : -1;
}).filter((length) => {
return length !== -1;
})) + 1;
return {
hasNoTypes,
maxNamedTagLength,
maxUnnamedTagLength,
};
};

const space = (len) => {
return ''.padStart(len, ' ');
};
Expand All @@ -79,7 +108,7 @@ const alignTransform = ({
let intoTags = false;
let width;

const alignTokens = (tokens, hasNoTypes) => {
const alignTokens = (tokens, typelessInfo) => {
const nothingAfter = {
delim: false,
name: false,
Expand Down Expand Up @@ -107,9 +136,18 @@ const alignTransform = ({
}
}

if (hasNoTypes) {
let untypedNameAdjustment = 0;
let untypedTypeAdjustment = 0;
if (typelessInfo.hasNoTypes) {
nothingAfter.tag = true;
tokens.postTag = '';
if (tokens.name === '') {
untypedNameAdjustment = typelessInfo.maxNamedTagLength - tokens.tag.length;
} else {
untypedNameAdjustment = typelessInfo.maxNamedTagLength > typelessInfo.maxUnnamedTagLength ? 0 :
Math.max(0, typelessInfo.maxUnnamedTagLength - (tokens.tag.length + tokens.name.length + 1));
untypedTypeAdjustment = typelessInfo.maxNamedTagLength - tokens.tag.length;
}
}

// Todo: Avoid fixing alignment of blocks with multiline wrapping of type
Expand All @@ -131,18 +169,18 @@ const alignTransform = ({
}

if (!nothingAfter.type) {
tokens.postType = space(width.type - tokens.type.length + spacings.postType);
tokens.postType = space(width.type - tokens.type.length + spacings.postType + untypedTypeAdjustment);
}

if (!nothingAfter.name) {
// If post name is empty for all lines (name width 0), don't add post name spacing.
tokens.postName = width.name === 0 ? '' : space(width.name - tokens.name.length + spacings.postName);
tokens.postName = width.name === 0 ? '' : space(width.name - tokens.name.length + spacings.postName + untypedNameAdjustment);
}

return tokens;
};

const update = (line, index, source, hasNoTypes) => {
const update = (line, index, source, typelessInfo) => {
const tokens = {
...line.tokens,
};
Expand Down Expand Up @@ -205,7 +243,7 @@ const alignTransform = ({

return {
...line,
tokens: alignTokens(tokens, hasNoTypes),
tokens: alignTokens(tokens, typelessInfo),
};
};

Expand All @@ -216,16 +254,13 @@ const alignTransform = ({
width = source.reduce(getWidth(tags), {
...zeroWidth,
});
const hasNoTypes = fields.tags.every(({
type,
}) => {
return !type;
});

const typelessInfo = getTypelessInfo(fields);

return rewireSource({
...fields,
source: source.map((line, index) => {
return update(line, index, source, hasNoTypes);
return update(line, index, source, typelessInfo);
}),
});
};
Expand Down
98 changes: 98 additions & 0 deletions test/rules/assertions/checkLineAlignment.js
Expand Up @@ -1577,5 +1577,103 @@ export default {
'always',
],
},
{
code: `
/**
* Function description.
*
* @param lorem Description.
* @param sit Description multi words.
* @return Return description.
*/
const fn = ( lorem, sit ) => {};
/**
* Function description.
*
* @param lorem Description.
* @param sit Description multi words.
* @returns Return description.
*/
const fn2 = ( lorem, sit ) => {};
/**
* Function description.
*
* @param a Description.
* @param b Description multi words.
* @returns Return description.
*/
const fn3 = ( a, b ) => {};
`,
options: [
'always',
],
},
{
code: `
/**
* Function description.
*
* @argument lorem Description.
* @return Return description.
*/
const fn = ( lorem ) => {};
/**
* Function description.
*
* @argument lorem Description.
* @returns Return description.
*/
const fn2 = ( lorem ) => {};
`,
options: [
'always',
],
},
{
code: `
/**
* Function description.
*
* @arg a Description.
* @returns Return description.
*/
const fn = ( a ) => {};
`,
options: [
'always',
],
},
{
code: `
/**
* Function description.
*
* @arg lorem Description.
* @param sit Return description.
*/
const fn = ( lorem, sit ) => {};
`,
options: [
'always',
],
},
{
code: `
/**
* Function description.
*
* @arg a Description.
* @argument b Second description.
* @returns Return description.
*/
const fn = ( a, b ) => {};
`,
options: [
'always',
],
},
],
};

0 comments on commit fe0e209

Please sign in to comment.