Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

jsdoc-format: check first line of multiline comment #3181

Merged
merged 5 commits into from
Sep 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/configs/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export const rules = {
"import-spacing": true,
"interface-name": true,
"interface-over-type-literal": true,
"jsdoc-format": true,
"jsdoc-format": [true, "check-multiline-start"],
"match-default-export-name": true,
"new-parens": true,
"newline-before-return": true,
Expand Down
5 changes: 4 additions & 1 deletion src/configs/latest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ export const rules = {
],
},

// added in v5.8.0
// added in v5.8
"no-duplicate-switch-case": true,
"jsdoc-format": {
options: "check-multiline-start",
},
};
// tslint:enable object-literal-sort-keys

Expand Down
37 changes: 31 additions & 6 deletions src/rules/jsdocFormatRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import * as ts from "typescript";

import * as Lint from "../index";

const OPTION_CHECK_MULTILINE_START = "check-multiline-start";

export class Rule extends Lint.Rules.AbstractRule {
/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
Expand All @@ -31,11 +33,24 @@ export class Rule extends Lint.Rules.AbstractRule {
* each line contains an asterisk and asterisks must be aligned
* each asterisk must be followed by either a space or a newline (except for the first and the last)
* the only characters before the asterisk on each line must be whitespace characters
* one line comments must start with \`/** \` and end with \`*/\``,
* one line comments must start with \`/** \` and end with \`*/\`
* multiline comments don't allow text after \`/** \` in the first line (with option \`"${OPTION_CHECK_MULTILINE_START}"\`)
`,
rationale: "Helps maintain a consistent, readable style for JSDoc comments.",
optionsDescription: "Not configurable.",
options: null,
optionExamples: [true],
optionsDescription: Lint.Utils.dedent`
You can optionally specify the option \`"${OPTION_CHECK_MULTILINE_START}"\` to enforce the first line of a
multiline JSDoc comment to be empty.
`,
options: {
type: "array",
minItems: 0,
maxItems: 1,
items: {
type: "string",
enum: [OPTION_CHECK_MULTILINE_START],
},
},
optionExamples: [true, [true, OPTION_CHECK_MULTILINE_START]],
type: "style",
typescriptOnly: false,
};
Expand All @@ -45,11 +60,17 @@ export class Rule extends Lint.Rules.AbstractRule {
public static FORMAT_FAILURE_STRING = "jsdoc is not formatted correctly on this line";

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithFunction(sourceFile, walk);
return this.applyWithFunction(sourceFile, walk, {
firstLineOfMultiline: this.ruleArguments.indexOf(OPTION_CHECK_MULTILINE_START) !== -1,
});
}
}

function walk(ctx: Lint.WalkContext<void>) {
interface Options {
firstLineOfMultiline: boolean;
}

function walk(ctx: Lint.WalkContext<Options>) {
return utils.forEachComment(ctx.sourceFile, (fullText, {kind, pos, end}) => {
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia ||
fullText[pos + 2] !== "*" || fullText[pos + 3] === "*" || fullText[pos + 3] === "/") {
Expand All @@ -65,6 +86,10 @@ function walk(ctx: Lint.WalkContext<void>) {
}

const alignColumn = getAlignColumn(ctx.sourceFile, pos + 1);
if (ctx.options.firstLineOfMultiline && /\S/.test(firstLine)) {
// first line of multiline JSDoc should be empty, i.e. only contain whitespace
ctx.addFailureAt(pos, firstLine.length + 3, Rule.FORMAT_FAILURE_STRING);
}
let lineStart = pos + firstLine.length + 4; // +3 for the comment start "/**" and +1 for the newline
const endIndex = lines.length - 1;
for (let i = 1; i < endIndex; ++i) {
Expand Down
10 changes: 10 additions & 0 deletions test/rules/jsdoc-format/check-multiline-start/test.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** First line of multiline jsdoc
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [jsdoc is not formatted correctly on this line]
* should be empty.
*/

/**
* Good multiline.
*/

/** Good singleline */
5 changes: 5 additions & 0 deletions test/rules/jsdoc-format/check-multiline-start/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"jsdoc-format": [true, "check-multiline-start"]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ one *

/**/ // no jsdoc

/** First line of multiline jsdoc
* should be empty.
*/
}

// Regression test: jsdoc rule shouldn't look inside template strings (https://github.com/palantir/tslint/issues/332)
Expand Down