eslint-plugin-complete 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +114 -0
- package/dist/comments.d.ts +22 -0
- package/dist/comments.d.ts.map +1 -0
- package/dist/comments.js +66 -0
- package/dist/completeCommon.d.ts +25 -0
- package/dist/completeCommon.d.ts.map +1 -0
- package/dist/completeCommon.js +53 -0
- package/dist/completeSentence.d.ts +9 -0
- package/dist/completeSentence.d.ts.map +1 -0
- package/dist/completeSentence.js +267 -0
- package/dist/configs/recommended.d.ts +3 -0
- package/dist/configs/recommended.d.ts.map +1 -0
- package/dist/configs/recommended.js +63 -0
- package/dist/configs.d.ts +4 -0
- package/dist/configs.d.ts.map +1 -0
- package/dist/configs.js +4 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +73 -0
- package/dist/format.d.ts +18 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +246 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/interfaces/MyPluginDocs.d.ts +6 -0
- package/dist/interfaces/MyPluginDocs.d.ts.map +1 -0
- package/dist/interfaces/MyPluginDocs.js +1 -0
- package/dist/jsdoc.d.ts +4 -0
- package/dist/jsdoc.d.ts.map +1 -0
- package/dist/jsdoc.js +24 -0
- package/dist/leadingLineComments.d.ts +32 -0
- package/dist/leadingLineComments.d.ts.map +1 -0
- package/dist/leadingLineComments.js +77 -0
- package/dist/list.d.ts +49 -0
- package/dist/list.d.ts.map +1 -0
- package/dist/list.js +140 -0
- package/dist/rules/complete-sentences-jsdoc.d.ts +4 -0
- package/dist/rules/complete-sentences-jsdoc.d.ts.map +1 -0
- package/dist/rules/complete-sentences-jsdoc.js +48 -0
- package/dist/rules/complete-sentences-line-comments.d.ts +4 -0
- package/dist/rules/complete-sentences-line-comments.d.ts.map +1 -0
- package/dist/rules/complete-sentences-line-comments.js +88 -0
- package/dist/rules/consistent-enum-values.d.ts +2 -0
- package/dist/rules/consistent-enum-values.d.ts.map +1 -0
- package/dist/rules/consistent-enum-values.js +46 -0
- package/dist/rules/consistent-named-tuples.d.ts +2 -0
- package/dist/rules/consistent-named-tuples.d.ts.map +1 -0
- package/dist/rules/consistent-named-tuples.js +34 -0
- package/dist/rules/eqeqeq-fix.d.ts +2 -0
- package/dist/rules/eqeqeq-fix.d.ts.map +1 -0
- package/dist/rules/eqeqeq-fix.js +173 -0
- package/dist/rules/format-jsdoc-comments.d.ts +8 -0
- package/dist/rules/format-jsdoc-comments.d.ts.map +1 -0
- package/dist/rules/format-jsdoc-comments.js +117 -0
- package/dist/rules/format-line-comments.d.ts +8 -0
- package/dist/rules/format-line-comments.d.ts.map +1 -0
- package/dist/rules/format-line-comments.js +118 -0
- package/dist/rules/jsdoc-code-block-language.d.ts +2 -0
- package/dist/rules/jsdoc-code-block-language.d.ts.map +1 -0
- package/dist/rules/jsdoc-code-block-language.js +52 -0
- package/dist/rules/newline-between-switch-case.d.ts +4 -0
- package/dist/rules/newline-between-switch-case.d.ts.map +1 -0
- package/dist/rules/newline-between-switch-case.js +63 -0
- package/dist/rules/no-confusing-set-methods.d.ts +5 -0
- package/dist/rules/no-confusing-set-methods.d.ts.map +1 -0
- package/dist/rules/no-confusing-set-methods.js +51 -0
- package/dist/rules/no-empty-jsdoc.d.ts +2 -0
- package/dist/rules/no-empty-jsdoc.d.ts.map +1 -0
- package/dist/rules/no-empty-jsdoc.js +45 -0
- package/dist/rules/no-empty-line-comments.d.ts +2 -0
- package/dist/rules/no-empty-line-comments.d.ts.map +1 -0
- package/dist/rules/no-empty-line-comments.js +40 -0
- package/dist/rules/no-explicit-array-loops.d.ts +5 -0
- package/dist/rules/no-explicit-array-loops.d.ts.map +1 -0
- package/dist/rules/no-explicit-array-loops.js +114 -0
- package/dist/rules/no-explicit-map-set-loops.d.ts +5 -0
- package/dist/rules/no-explicit-map-set-loops.d.ts.map +1 -0
- package/dist/rules/no-explicit-map-set-loops.js +74 -0
- package/dist/rules/no-for-in.d.ts +2 -0
- package/dist/rules/no-for-in.d.ts.map +1 -0
- package/dist/rules/no-for-in.js +27 -0
- package/dist/rules/no-let-any.d.ts +3 -0
- package/dist/rules/no-let-any.d.ts.map +1 -0
- package/dist/rules/no-let-any.js +45 -0
- package/dist/rules/no-mutable-return.d.ts +5 -0
- package/dist/rules/no-mutable-return.d.ts.map +1 -0
- package/dist/rules/no-mutable-return.js +63 -0
- package/dist/rules/no-number-enums.d.ts +2 -0
- package/dist/rules/no-number-enums.d.ts.map +1 -0
- package/dist/rules/no-number-enums.js +27 -0
- package/dist/rules/no-object-any.d.ts +3 -0
- package/dist/rules/no-object-any.d.ts.map +1 -0
- package/dist/rules/no-object-any.js +51 -0
- package/dist/rules/no-object-methods-with-map-set.d.ts +5 -0
- package/dist/rules/no-object-methods-with-map-set.d.ts.map +1 -0
- package/dist/rules/no-object-methods-with-map-set.js +84 -0
- package/dist/rules/no-string-length-0.d.ts +3 -0
- package/dist/rules/no-string-length-0.d.ts.map +1 -0
- package/dist/rules/no-string-length-0.js +52 -0
- package/dist/rules/no-template-curly-in-string-fix.d.ts +6 -0
- package/dist/rules/no-template-curly-in-string-fix.d.ts.map +1 -0
- package/dist/rules/no-template-curly-in-string-fix.js +39 -0
- package/dist/rules/no-undefined-return-type.d.ts +3 -0
- package/dist/rules/no-undefined-return-type.d.ts.map +1 -0
- package/dist/rules/no-undefined-return-type.js +40 -0
- package/dist/rules/no-unnecessary-assignment.d.ts +5 -0
- package/dist/rules/no-unnecessary-assignment.d.ts.map +1 -0
- package/dist/rules/no-unnecessary-assignment.js +255 -0
- package/dist/rules/no-unsafe-plusplus.d.ts +2 -0
- package/dist/rules/no-unsafe-plusplus.d.ts.map +1 -0
- package/dist/rules/no-unsafe-plusplus.js +34 -0
- package/dist/rules/no-useless-return.d.ts +2 -0
- package/dist/rules/no-useless-return.d.ts.map +1 -0
- package/dist/rules/no-useless-return.js +347 -0
- package/dist/rules/no-void-return-type.d.ts +2 -0
- package/dist/rules/no-void-return-type.d.ts.map +1 -0
- package/dist/rules/no-void-return-type.js +49 -0
- package/dist/rules/prefer-const.d.ts +2 -0
- package/dist/rules/prefer-const.d.ts.map +1 -0
- package/dist/rules/prefer-const.js +426 -0
- package/dist/rules/prefer-plusplus.d.ts +5 -0
- package/dist/rules/prefer-plusplus.d.ts.map +1 -0
- package/dist/rules/prefer-plusplus.js +49 -0
- package/dist/rules/prefer-postfix-plusplus.d.ts +2 -0
- package/dist/rules/prefer-postfix-plusplus.d.ts.map +1 -0
- package/dist/rules/prefer-postfix-plusplus.js +32 -0
- package/dist/rules/prefer-readonly-parameter-types.d.ts +13 -0
- package/dist/rules/prefer-readonly-parameter-types.d.ts.map +1 -0
- package/dist/rules/prefer-readonly-parameter-types.js +140 -0
- package/dist/rules/require-break.d.ts +5 -0
- package/dist/rules/require-break.d.ts.map +1 -0
- package/dist/rules/require-break.js +76 -0
- package/dist/rules/require-capital-const-assertions.d.ts +4 -0
- package/dist/rules/require-capital-const-assertions.d.ts.map +1 -0
- package/dist/rules/require-capital-const-assertions.js +112 -0
- package/dist/rules/require-capital-read-only.d.ts +5 -0
- package/dist/rules/require-capital-read-only.d.ts.map +1 -0
- package/dist/rules/require-capital-read-only.js +111 -0
- package/dist/rules/require-unannotated-const-assertions.d.ts +2 -0
- package/dist/rules/require-unannotated-const-assertions.d.ts.map +1 -0
- package/dist/rules/require-unannotated-const-assertions.js +27 -0
- package/dist/rules/require-variadic-function-argument.d.ts +5 -0
- package/dist/rules/require-variadic-function-argument.d.ts.map +1 -0
- package/dist/rules/require-variadic-function-argument.js +86 -0
- package/dist/rules/strict-array-methods.d.ts +3 -0
- package/dist/rules/strict-array-methods.d.ts.map +1 -0
- package/dist/rules/strict-array-methods.js +83 -0
- package/dist/rules/strict-enums.d.ts +5 -0
- package/dist/rules/strict-enums.d.ts.map +1 -0
- package/dist/rules/strict-enums.js +445 -0
- package/dist/rules/strict-undefined-functions.d.ts +5 -0
- package/dist/rules/strict-undefined-functions.d.ts.map +1 -0
- package/dist/rules/strict-undefined-functions.js +49 -0
- package/dist/rules/strict-void-functions.d.ts +2 -0
- package/dist/rules/strict-void-functions.d.ts.map +1 -0
- package/dist/rules/strict-void-functions.js +43 -0
- package/dist/rules.d.ts +49 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +85 -0
- package/dist/template.d.ts +2 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/template.js +29 -0
- package/dist/typeUtils.d.ts +28 -0
- package/dist/typeUtils.d.ts.map +1 -0
- package/dist/typeUtils.js +76 -0
- package/dist/utils.d.ts +13 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +54 -0
- package/package.json +55 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { isCommentOnOwnLine, isSeparatorLine } from "./comments.js";
|
|
3
|
+
export function getLeadingLineComments(sourceCode, comments) {
|
|
4
|
+
return comments.filter((comment) => comment.type === TSESTree.AST_TOKEN_TYPES.Line && // i.e. a "//" comment
|
|
5
|
+
comment.value.trim() !== "" &&
|
|
6
|
+
!comment.value.startsWith("/") && // Filter out triple slash directives
|
|
7
|
+
isCommentOnOwnLine(sourceCode, comment));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Returns an array of grouped comments. For example, the following code would return an array of
|
|
11
|
+
* three comment blocks:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* // This is the first block.
|
|
15
|
+
*
|
|
16
|
+
* // This is the second block.
|
|
17
|
+
* // We are still in the second block, because there has not been a newline separator yet.
|
|
18
|
+
*
|
|
19
|
+
* // This is the third block.
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function getCommentBlocks(comments) {
|
|
23
|
+
const commentBlocks = [];
|
|
24
|
+
// We cannot use the `comments.entries` method because we mutate `i`.
|
|
25
|
+
for (let i = 0; i < comments.length; i++) {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
27
|
+
const comment = comments[i];
|
|
28
|
+
/**
|
|
29
|
+
* Remove the initial space that will always live in front of comment line.
|
|
30
|
+
*
|
|
31
|
+
* For example, the comment of:
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* // Foo.
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* Has a comment value of: " Foo."
|
|
38
|
+
*/
|
|
39
|
+
const firstCharacter = comment.value[0];
|
|
40
|
+
const firstCharacterIsSpace = firstCharacter !== undefined && firstCharacter === " ";
|
|
41
|
+
const text = firstCharacterIsSpace ? comment.value.slice(1) : comment.value;
|
|
42
|
+
const commentBlock = {
|
|
43
|
+
mergedText: text,
|
|
44
|
+
originalComments: [comment],
|
|
45
|
+
};
|
|
46
|
+
const commentIndex = i; // Make a copy of the comment index since we will mutate i later.
|
|
47
|
+
const firstCommentStartLine = comment.loc.start.line;
|
|
48
|
+
// Look for one or more "connecting" comments on the next subsequent lines.
|
|
49
|
+
for (let j = i + 1; j < comments.length; j++) {
|
|
50
|
+
const nextComment = comments[j];
|
|
51
|
+
if (nextComment === undefined) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
// Break if we are on a non-contiguous line.
|
|
55
|
+
const nextCommentStartLine = nextComment.loc.start.line;
|
|
56
|
+
const lineDelta = j - commentIndex;
|
|
57
|
+
if (nextCommentStartLine !== firstCommentStartLine + lineDelta) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
// Break if this is a "separator" line.
|
|
61
|
+
if (isSeparatorLine(nextComment.value)) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
commentBlock.mergedText += "\n";
|
|
65
|
+
const nextText = nextComment.value.slice(1);
|
|
66
|
+
commentBlock.mergedText += nextText;
|
|
67
|
+
commentBlock.originalComments.push(nextComment);
|
|
68
|
+
// Since we merged this comment, we can skip over examining it in the parent loop.
|
|
69
|
+
i++;
|
|
70
|
+
}
|
|
71
|
+
commentBlocks.push(commentBlock);
|
|
72
|
+
}
|
|
73
|
+
return commentBlocks;
|
|
74
|
+
}
|
|
75
|
+
export function allCommentsInBlockAreCommentedOutArrayElements(commentBlock) {
|
|
76
|
+
return commentBlock.originalComments.every((comment) => comment.value.match(/^\s*"[^"]*",\s*$/) !== null);
|
|
77
|
+
}
|
package/dist/list.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A description of the kind of list that is currently being iterated over. For example, the
|
|
3
|
+
* following text is a list:
|
|
4
|
+
*
|
|
5
|
+
* ```text
|
|
6
|
+
* 1. Apple
|
|
7
|
+
* 2. Banana
|
|
8
|
+
* 3. Pear
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export interface List {
|
|
12
|
+
kind: ListKind;
|
|
13
|
+
/** The size of the whitespace prior to the marker. For example, " 1. Foo" would be 2. */
|
|
14
|
+
numLeadingSpaces: number;
|
|
15
|
+
/**
|
|
16
|
+
* The size of the characters that make up the bullet point.
|
|
17
|
+
* e.g. "1. Foo" would be 3.
|
|
18
|
+
*/
|
|
19
|
+
markerSize: number;
|
|
20
|
+
/**
|
|
21
|
+
* The contents of JSDoc tag header, if any.
|
|
22
|
+
* e.g. "@param foo This is foo." would be "@param foo".
|
|
23
|
+
*/
|
|
24
|
+
jsDocTagName?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare enum ListKind {
|
|
27
|
+
Hyphen = "Hyphen",
|
|
28
|
+
NumberParenthesis = "NumberParenthesis",
|
|
29
|
+
NumberPeriod = "NumberPeriod",
|
|
30
|
+
JSDocTag = "JSDocTag"
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* When using the `getList` function, the returned list may not be accurate if this is a line that
|
|
34
|
+
* is continuing from the previous line. For example:
|
|
35
|
+
*
|
|
36
|
+
* ```text
|
|
37
|
+
* This method will crash the game if you provide it an invalid number, such as 10000000000000000 or
|
|
38
|
+
* 43. (Using 0 will not cause a crash.)
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* Here, "43. " is incorrectly interpreted as the beginning of a list. In order to work around this
|
|
42
|
+
* problem, use the `getAdjustedList` function instead.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getAdjustedList(line: string, previousLineWasBlank: boolean, previousLineEndedInColon: boolean, insideList: List | undefined): List | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* When iterating over lines of text, by default, we want to keep the existing list object, if any.
|
|
47
|
+
*/
|
|
48
|
+
export declare function reachedNewList(insideList: List | undefined, list: List | undefined): boolean;
|
|
49
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,QAAQ,CAAC;IAEf,yFAAyF;IACzF,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,oBAAY,QAAQ;IAClB,MAAM,WAAW;IACjB,iBAAiB,sBAAsB;IACvC,YAAY,iBAAiB;IAC7B,QAAQ,aAAa;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,oBAAoB,EAAE,OAAO,EAC7B,wBAAwB,EAAE,OAAO,EACjC,UAAU,EAAE,IAAI,GAAG,SAAS,GAC3B,IAAI,GAAG,SAAS,CAgClB;AAqGD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,IAAI,GAAG,SAAS,EAC5B,IAAI,EAAE,IAAI,GAAG,SAAS,GACrB,OAAO,CAUT"}
|
package/dist/list.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export var ListKind;
|
|
2
|
+
(function (ListKind) {
|
|
3
|
+
ListKind["Hyphen"] = "Hyphen";
|
|
4
|
+
ListKind["NumberParenthesis"] = "NumberParenthesis";
|
|
5
|
+
ListKind["NumberPeriod"] = "NumberPeriod";
|
|
6
|
+
ListKind["JSDocTag"] = "JSDocTag";
|
|
7
|
+
})(ListKind || (ListKind = {}));
|
|
8
|
+
/**
|
|
9
|
+
* When using the `getList` function, the returned list may not be accurate if this is a line that
|
|
10
|
+
* is continuing from the previous line. For example:
|
|
11
|
+
*
|
|
12
|
+
* ```text
|
|
13
|
+
* This method will crash the game if you provide it an invalid number, such as 10000000000000000 or
|
|
14
|
+
* 43. (Using 0 will not cause a crash.)
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Here, "43. " is incorrectly interpreted as the beginning of a list. In order to work around this
|
|
18
|
+
* problem, use the `getAdjustedList` function instead.
|
|
19
|
+
*/
|
|
20
|
+
export function getAdjustedList(line, previousLineWasBlank, previousLineEndedInColon, insideList) {
|
|
21
|
+
const list = getList(line);
|
|
22
|
+
if (list === undefined) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
switch (list.kind) {
|
|
26
|
+
case ListKind.Hyphen: {
|
|
27
|
+
return list;
|
|
28
|
+
}
|
|
29
|
+
case ListKind.NumberPeriod:
|
|
30
|
+
case ListKind.NumberParenthesis: {
|
|
31
|
+
// If we are already inside of a numbered list, then do not require blank lines in between the
|
|
32
|
+
// bullets.
|
|
33
|
+
if (list.kind === insideList?.kind) {
|
|
34
|
+
return list;
|
|
35
|
+
}
|
|
36
|
+
// If the previous line had a colon, then do not require blank lines in between the bullets.
|
|
37
|
+
if (previousLineEndedInColon) {
|
|
38
|
+
return list;
|
|
39
|
+
}
|
|
40
|
+
// Otherwise, only interpret this as a bulleted list if the previous line was blank.
|
|
41
|
+
return previousLineWasBlank ? list : undefined;
|
|
42
|
+
}
|
|
43
|
+
case ListKind.JSDocTag: {
|
|
44
|
+
return list;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function getList(line) {
|
|
49
|
+
const originalLength = line.length;
|
|
50
|
+
line = line.trimStart();
|
|
51
|
+
const trimmedLength = line.length;
|
|
52
|
+
const numLeadingSpaces = originalLength - trimmedLength;
|
|
53
|
+
// e.g. "- A bullet point can start with a hyphen."
|
|
54
|
+
if (line.startsWith("- ")) {
|
|
55
|
+
return {
|
|
56
|
+
kind: ListKind.Hyphen,
|
|
57
|
+
numLeadingSpaces,
|
|
58
|
+
markerSize: "- ".length,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** e.g. "1. A bullet point can start with a number and a period." */
|
|
62
|
+
const numberPeriodMatch = line.match(/^(\d+)\. /);
|
|
63
|
+
if (numberPeriodMatch !== null &&
|
|
64
|
+
numberPeriodMatch[1] !== undefined &&
|
|
65
|
+
numberPeriodMatch[1] !== "0") {
|
|
66
|
+
return {
|
|
67
|
+
kind: ListKind.NumberPeriod,
|
|
68
|
+
numLeadingSpaces,
|
|
69
|
+
markerSize: numberPeriodMatch[1].length + ". ".length,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** e.g. "1) A bullet point can start with a number and a parenthesis." */
|
|
73
|
+
const numberParenthesisMatch = line.match(/^(\d+)\) /);
|
|
74
|
+
if (numberParenthesisMatch !== null &&
|
|
75
|
+
numberParenthesisMatch[1] !== undefined &&
|
|
76
|
+
numberParenthesisMatch[1] !== "0") {
|
|
77
|
+
return {
|
|
78
|
+
kind: ListKind.NumberParenthesis,
|
|
79
|
+
numLeadingSpaces,
|
|
80
|
+
markerSize: numberParenthesisMatch[1].length + ") ".length,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const jsDocTagName = getJSDocTagName(line);
|
|
84
|
+
if (jsDocTagName !== undefined) {
|
|
85
|
+
return {
|
|
86
|
+
kind: ListKind.JSDocTag,
|
|
87
|
+
numLeadingSpaces,
|
|
88
|
+
markerSize: jsDocTagName.length + " ".length,
|
|
89
|
+
jsDocTagName,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Returns a string containing the param header, if any. For example, "@returns Foo" would return
|
|
96
|
+
* "@returns".
|
|
97
|
+
*
|
|
98
|
+
* For "@param" tags, the returned tag string will include the variable name, if any. For example,
|
|
99
|
+
* "@param foo Foo" would return "@param foo".
|
|
100
|
+
*/
|
|
101
|
+
function getJSDocTagName(text) {
|
|
102
|
+
text = text.trimStart();
|
|
103
|
+
if (!text.startsWith("@")) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const tagMatch = text.match(/^@(?<tagName>\w+)/);
|
|
107
|
+
if (tagMatch === null || tagMatch.groups === undefined) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const { tagName } = tagMatch.groups;
|
|
111
|
+
if (tagName === undefined) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
// Specific JSDoc tags have words after them that should be part of the tag for indenting
|
|
115
|
+
// purposes.
|
|
116
|
+
if (tagName === "param") {
|
|
117
|
+
const paramMatch = text.match(/^(?<tagWithVariableName>@\w+ \w+)/);
|
|
118
|
+
if (paramMatch === null || paramMatch.groups === undefined) {
|
|
119
|
+
return "@param";
|
|
120
|
+
}
|
|
121
|
+
const { tagWithVariableName } = paramMatch.groups;
|
|
122
|
+
if (tagWithVariableName === undefined) {
|
|
123
|
+
return "@param";
|
|
124
|
+
}
|
|
125
|
+
return tagWithVariableName;
|
|
126
|
+
}
|
|
127
|
+
return `@${tagName}`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* When iterating over lines of text, by default, we want to keep the existing list object, if any.
|
|
131
|
+
*/
|
|
132
|
+
export function reachedNewList(insideList, list) {
|
|
133
|
+
if (list === undefined) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return (insideList === undefined || // Going from a non-list to list
|
|
137
|
+
insideList.numLeadingSpaces !== list.numLeadingSpaces || // Going from a list to a sub-list
|
|
138
|
+
insideList.jsDocTagName !== list.jsDocTagName // Going from a JSDoc to a different JSDoc tag
|
|
139
|
+
);
|
|
140
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CompleteSentenceMessageIds } from "../completeSentence.js";
|
|
2
|
+
export type Options = [];
|
|
3
|
+
export declare const completeSentencesJSDoc: import("@typescript-eslint/utils/ts-eslint").RuleModule<CompleteSentenceMessageIds, [], import("../interfaces/MyPluginDocs.js").MyPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
4
|
+
//# sourceMappingURL=complete-sentences-jsdoc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-sentences-jsdoc.d.ts","sourceRoot":"","sources":["../../src/rules/complete-sentences-jsdoc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAKzE,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AAEzB,eAAO,MAAM,sBAAsB,0MAuDjC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getIncompleteSentences } from "../completeSentence.js";
|
|
2
|
+
import { getJSDocComments, getTextFromJSDocComment } from "../jsdoc.js";
|
|
3
|
+
import { createRule } from "../utils.js";
|
|
4
|
+
export const completeSentencesJSDoc = createRule({
|
|
5
|
+
name: "complete-sentences-jsdoc",
|
|
6
|
+
meta: {
|
|
7
|
+
type: "problem",
|
|
8
|
+
docs: {
|
|
9
|
+
description: "Requires complete sentences for JSDoc comments",
|
|
10
|
+
recommended: true,
|
|
11
|
+
requiresTypeChecking: false,
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
messages: {
|
|
15
|
+
missingCapital: "JSDoc comments must contain complete sentences with a capital letter.\n{{ sentence }}",
|
|
16
|
+
missingPeriod: "JSDoc comments must contain complete sentences with a trailing period.\n{{ sentence }}",
|
|
17
|
+
doublePeriod: "JSDoc comments must not end with a double period. Did you make a typo?.\n{{ sentence }}",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultOptions: [],
|
|
21
|
+
/**
|
|
22
|
+
* We need to write the rule in such a way that it operates on the entire source code instead of
|
|
23
|
+
* individual AST nodes:
|
|
24
|
+
* https://stackoverflow.com/questions/47429792/is-it-possible-to-get-comments-as-nodes-in-the-ast-using-the-typescript-compiler
|
|
25
|
+
*/
|
|
26
|
+
create(context) {
|
|
27
|
+
const comments = context.sourceCode.getAllComments();
|
|
28
|
+
// We only look at `/**` style comments.
|
|
29
|
+
const jsDocComments = getJSDocComments(comments);
|
|
30
|
+
for (const comment of jsDocComments) {
|
|
31
|
+
const text = getTextFromJSDocComment(comment.value);
|
|
32
|
+
const incompleteSentences = getIncompleteSentences(text);
|
|
33
|
+
for (const incompleteSentence of incompleteSentences) {
|
|
34
|
+
context.report({
|
|
35
|
+
loc: {
|
|
36
|
+
start: comment.loc.start,
|
|
37
|
+
end: comment.loc.end,
|
|
38
|
+
},
|
|
39
|
+
messageId: incompleteSentence.messageId,
|
|
40
|
+
data: {
|
|
41
|
+
sentence: incompleteSentence.sentence,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {};
|
|
47
|
+
},
|
|
48
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CompleteSentenceMessageIds } from "../completeSentence.js";
|
|
2
|
+
export type Options = [];
|
|
3
|
+
export declare const completeSentencesLineComments: import("@typescript-eslint/utils/ts-eslint").RuleModule<CompleteSentenceMessageIds, [], import("../interfaces/MyPluginDocs.js").MyPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
4
|
+
//# sourceMappingURL=complete-sentences-line-comments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete-sentences-line-comments.d.ts","sourceRoot":"","sources":["../../src/rules/complete-sentences-line-comments.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAUzE,MAAM,MAAM,OAAO,GAAG,EAAE,CAAC;AAEzB,eAAO,MAAM,6BAA6B,0MAuFxC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { isSeparatorLine } from "../comments.js";
|
|
2
|
+
import { assertDefined } from "../completeCommon.js";
|
|
3
|
+
import { getIncompleteSentences } from "../completeSentence.js";
|
|
4
|
+
import { JAVASCRIPT_RESERVED_WORDS_SET } from "../constants.js";
|
|
5
|
+
import { allCommentsInBlockAreCommentedOutArrayElements, getCommentBlocks, getLeadingLineComments, } from "../leadingLineComments.js";
|
|
6
|
+
import { createRule } from "../utils.js";
|
|
7
|
+
export const completeSentencesLineComments = createRule({
|
|
8
|
+
name: "complete-sentences-line-comments",
|
|
9
|
+
meta: {
|
|
10
|
+
type: "problem",
|
|
11
|
+
docs: {
|
|
12
|
+
description: "Requires complete sentences for multi-line leading line comments",
|
|
13
|
+
recommended: true,
|
|
14
|
+
requiresTypeChecking: false,
|
|
15
|
+
},
|
|
16
|
+
schema: [],
|
|
17
|
+
messages: {
|
|
18
|
+
missingCapital: "Leading line comments must contain complete sentences with a capital letter.\n{{ sentence }}",
|
|
19
|
+
missingPeriod: "Leading line comments must contain complete sentences with a trailing period.\n{{ sentence }}",
|
|
20
|
+
doublePeriod: "Leading line comments must not end with a double period. Did you make a typo?\n{{ sentence }}",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultOptions: [],
|
|
24
|
+
create(context) {
|
|
25
|
+
const { sourceCode } = context;
|
|
26
|
+
const comments = sourceCode.getAllComments();
|
|
27
|
+
// We only look at `//` style comments on their own line.
|
|
28
|
+
const leadingLineComments = getLeadingLineComments(sourceCode, comments);
|
|
29
|
+
// Sort the comments by blocks.
|
|
30
|
+
const commentBlocks = getCommentBlocks(leadingLineComments);
|
|
31
|
+
for (const [i, commentBlock] of commentBlocks.entries()) {
|
|
32
|
+
const firstComment = commentBlock.originalComments.at(0);
|
|
33
|
+
assertDefined(firstComment, "Failed to get the first comment.");
|
|
34
|
+
const lastComment = commentBlock.originalComments.at(-1);
|
|
35
|
+
assertDefined(lastComment, "Failed to get the last comment.");
|
|
36
|
+
// Commented out array elements are whitelisted.
|
|
37
|
+
if (allCommentsInBlockAreCommentedOutArrayElements(commentBlock)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Comments in-between "separator lines" are whitelisted.
|
|
41
|
+
const previousCommentBlock = commentBlocks[i - 1];
|
|
42
|
+
if (previousCommentBlock !== undefined &&
|
|
43
|
+
isSeparatorLine(previousCommentBlock.mergedText)) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const nextCommentBlock = commentBlocks[i + 1];
|
|
47
|
+
if (nextCommentBlock !== undefined &&
|
|
48
|
+
isSeparatorLine(nextCommentBlock.mergedText)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// Unlike JSDoc comments, we want to whitelist comment blocks that begin with JavaScript
|
|
52
|
+
// keywords. This is to make commenting out code less painful. e.g. `// const foo = 123;`
|
|
53
|
+
const text = commentBlock.mergedText;
|
|
54
|
+
const firstWord = getFirstWord(text);
|
|
55
|
+
if (JAVASCRIPT_RESERVED_WORDS_SET.has(firstWord)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const incompleteSentences = getIncompleteSentences(text);
|
|
59
|
+
for (const incompleteSentence of incompleteSentences) {
|
|
60
|
+
context.report({
|
|
61
|
+
loc: {
|
|
62
|
+
start: firstComment.loc.start,
|
|
63
|
+
end: lastComment.loc.end,
|
|
64
|
+
},
|
|
65
|
+
messageId: incompleteSentence.messageId,
|
|
66
|
+
data: {
|
|
67
|
+
sentence: incompleteSentence.sentence,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return {};
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
function getFirstWord(text) {
|
|
76
|
+
const words = text.split(" ");
|
|
77
|
+
const firstWord = words[0];
|
|
78
|
+
if (firstWord === undefined) {
|
|
79
|
+
return "";
|
|
80
|
+
}
|
|
81
|
+
// We want to match e.g. `console.log`.
|
|
82
|
+
const parts = firstWord.split(".");
|
|
83
|
+
const firstPart = parts[0];
|
|
84
|
+
if (firstPart === undefined) {
|
|
85
|
+
return "";
|
|
86
|
+
}
|
|
87
|
+
return firstPart;
|
|
88
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const consistentEnumValues: import("@typescript-eslint/utils/ts-eslint").RuleModule<"inconsistentValue", [], import("../interfaces/MyPluginDocs.js").MyPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
2
|
+
//# sourceMappingURL=consistent-enum-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consistent-enum-values.d.ts","sourceRoot":"","sources":["../../src/rules/consistent-enum-values.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,mMAgD/B,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createRule } from "../utils.js";
|
|
2
|
+
export const consistentEnumValues = createRule({
|
|
3
|
+
name: "consistent-enum-values",
|
|
4
|
+
meta: {
|
|
5
|
+
type: "problem",
|
|
6
|
+
docs: {
|
|
7
|
+
description: "Requires consistent enum values",
|
|
8
|
+
recommended: true,
|
|
9
|
+
requiresTypeChecking: false,
|
|
10
|
+
},
|
|
11
|
+
schema: [],
|
|
12
|
+
messages: {
|
|
13
|
+
inconsistentValue: "The value of an enum member must be a string that exactly matches the enum name.",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultOptions: [],
|
|
17
|
+
create(context) {
|
|
18
|
+
return {
|
|
19
|
+
TSEnumMember(node) {
|
|
20
|
+
// Ignore computed enums; those are intended to be checked with the
|
|
21
|
+
// `@typescript-eslint/prefer-enum-initializers` rule.
|
|
22
|
+
const { initializer } = node;
|
|
23
|
+
if (initializer === undefined || !("value" in initializer)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Ignore number enums; those are intended to be checked with the `complete/no-number-enums`
|
|
27
|
+
// rule.
|
|
28
|
+
const enumValue = initializer.value;
|
|
29
|
+
if (typeof enumValue !== "string") {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const { id } = node;
|
|
33
|
+
if (!("name" in id)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const enumName = id.name;
|
|
37
|
+
if (enumValue !== enumName) {
|
|
38
|
+
context.report({
|
|
39
|
+
node,
|
|
40
|
+
messageId: "inconsistentValue",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const consistentNamedTuples: import("@typescript-eslint/utils/ts-eslint").RuleModule<"notNamed", [], import("../interfaces/MyPluginDocs.js").MyPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
2
|
+
//# sourceMappingURL=consistent-named-tuples.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consistent-named-tuples.d.ts","sourceRoot":"","sources":["../../src/rules/consistent-named-tuples.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,0LAqChC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AST_NODE_TYPES } from "@typescript-eslint/utils";
|
|
2
|
+
import { createRule } from "../utils.js";
|
|
3
|
+
export const consistentNamedTuples = createRule({
|
|
4
|
+
name: "consistent-named-tuples",
|
|
5
|
+
meta: {
|
|
6
|
+
type: "problem",
|
|
7
|
+
docs: {
|
|
8
|
+
description: "Requires that if one or more tuple elements are named, all of them are named",
|
|
9
|
+
recommended: true,
|
|
10
|
+
requiresTypeChecking: false,
|
|
11
|
+
},
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
notNamed: "If one element in a tuple has a label, then all of them must have a label.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultOptions: [],
|
|
18
|
+
create(context) {
|
|
19
|
+
return {
|
|
20
|
+
TSTupleType(node) {
|
|
21
|
+
const hasNamedElements = node.elementTypes.some((typeNode) => typeNode.type === AST_NODE_TYPES.TSNamedTupleMember);
|
|
22
|
+
if (hasNamedElements) {
|
|
23
|
+
const hasAllNamedElements = node.elementTypes.every((typeNode) => typeNode.type === AST_NODE_TYPES.TSNamedTupleMember);
|
|
24
|
+
if (!hasAllNamedElements) {
|
|
25
|
+
context.report({
|
|
26
|
+
loc: node.loc,
|
|
27
|
+
messageId: "notNamed",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eqeqeq-fix.d.ts","sourceRoot":"","sources":["../../src/rules/eqeqeq-fix.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,SAAS,4LAkKpB,CAAC"}
|