in src/rules/noRedundantJsdoc2Rule.ts [134:200]
function removeTag(tag: ts.JSDocTag, sourceFile: ts.SourceFile): Lint.Replacement | undefined {
const { text } = sourceFile;
const jsdoc = tag.parent;
if (jsdoc.kind === ts.SyntaxKind.JSDocTypeLiteral) {
return undefined;
}
if (jsdoc.comment === undefined && jsdoc.tags!.length === 1) {
// This is the only tag -- remove the whole comment
return Lint.Replacement.deleteFromTo(jsdoc.getStart(sourceFile), jsdoc.getEnd());
}
let start = tag.getStart(sourceFile);
assert(text[start] === "@");
start--;
while (ts.isWhiteSpaceSingleLine(text.charCodeAt(start))) {
start--;
}
if (text[start] !== "*") {
return undefined;
}
let end = tag.getEnd();
// For some tags, like `@param`, `end` will be the start of the next tag.
// For some tags, like `@name`, `end` will be before the start of the comment.
// And `@typedef` doesn't end until the last `@property` tag attached to it ends.
switch (tag.tagName.text) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore (fallthrough)
case "param": {
const { isBracketed, isNameFirst, typeExpression } = tag as ts.JSDocParameterTag;
if (!isBracketed && !(isNameFirst && typeExpression !== undefined)) {
break;
}
// falls through
}
// eslint-disable-next-line no-fallthrough
case "name":
case "return":
case "returns":
case "interface":
case "default":
case "memberof":
case "memberOf":
case "method":
case "type":
case "class":
case "property":
case "function":
end--; // Might end with "\n" (test with just `@return` with no comment or type)
// For some reason, for "@name", "end" is before the start of the comment part of the tag.
// Also for "param" if the name is optional as in `@param {number} [x]`
while (!ts.isLineBreak(text.charCodeAt(end))) {
end++;
}
end++;
}
while (ts.isWhiteSpaceSingleLine(text.charCodeAt(end))) {
end++;
}
if (text[end] !== "*") {
return undefined;
}
return Lint.Replacement.deleteFromTo(start, end);
}