mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-15 05:55:11 -05:00
boolean-trivia lint rule: Enforce space between comment and argument
This commit is contained in:
@@ -8,7 +8,8 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
}
|
||||
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, function recur(node: ts.Node): void {
|
||||
const { sourceFile } = ctx;
|
||||
ts.forEachChild(sourceFile, function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.CallExpression) {
|
||||
checkCall(node as ts.CallExpression);
|
||||
}
|
||||
@@ -16,61 +17,79 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
});
|
||||
|
||||
function checkCall(node: ts.CallExpression): void {
|
||||
for (const arg of node.arguments) {
|
||||
switch (arg.kind) {
|
||||
case ts.SyntaxKind.TrueKeyword:
|
||||
case ts.SyntaxKind.FalseKeyword:
|
||||
case ts.SyntaxKind.NullKeyword:
|
||||
break;
|
||||
case ts.SyntaxKind.Identifier:
|
||||
if ((arg as ts.Identifier).originalKeywordKind !== ts.SyntaxKind.UndefinedKeyword) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node.expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
||||
const methodName = (node.expression as ts.PropertyAccessExpression).name.text;
|
||||
// Skip certain method names whose parameter names are not informative
|
||||
if (methodName.indexOf("set") === 0) {
|
||||
continue;
|
||||
}
|
||||
switch (methodName) {
|
||||
case "apply":
|
||||
case "assert":
|
||||
case "call":
|
||||
case "equal":
|
||||
case "fail":
|
||||
case "isTrue":
|
||||
case "output":
|
||||
case "stringify":
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (node.expression.kind === ts.SyntaxKind.Identifier) {
|
||||
const functionName = (node.expression as ts.Identifier).text;
|
||||
// Skip certain function names whose parameter names are not informative
|
||||
if (functionName.indexOf("set") === 0) {
|
||||
continue;
|
||||
}
|
||||
switch (functionName) {
|
||||
case "assert":
|
||||
case "contains":
|
||||
case "createAnonymousType":
|
||||
case "createImportSpecifier":
|
||||
case "createProperty":
|
||||
case "createSignature":
|
||||
case "resolveName":
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
|
||||
if (!(ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia)) {
|
||||
ctx.addFailureAtNode(arg, 'Tag boolean argument with parameter name');
|
||||
if (!shouldIgnoreCalledExpression(node.expression)) {
|
||||
for (const arg of node.arguments) {
|
||||
checkArg(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Skip certain function/method names whose parameter names are not informative. */
|
||||
function shouldIgnoreCalledExpression(expression: ts.Expression): boolean {
|
||||
if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
||||
const methodName = (expression as ts.PropertyAccessExpression).name.text;
|
||||
if (methodName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
switch (methodName) {
|
||||
case "apply":
|
||||
case "assert":
|
||||
case "call":
|
||||
case "equal":
|
||||
case "fail":
|
||||
case "isTrue":
|
||||
case "output":
|
||||
case "stringify":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (expression.kind === ts.SyntaxKind.Identifier) {
|
||||
const functionName = (expression as ts.Identifier).text;
|
||||
if (functionName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
switch (functionName) {
|
||||
case "assert":
|
||||
case "contains":
|
||||
case "createAnonymousType":
|
||||
case "createImportSpecifier":
|
||||
case "createProperty":
|
||||
case "createSignature":
|
||||
case "resolveName":
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkArg(arg: ts.Expression): void {
|
||||
if (!isTrivia(arg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ranges = ts.getTrailingCommentRanges(sourceFile.text, arg.pos) || ts.getLeadingCommentRanges(sourceFile.text, arg.pos);
|
||||
if (ranges === undefined || ranges.length !== 1 || ranges[0].kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
||||
ctx.addFailureAtNode(arg, "Tag boolean argument with parameter name");
|
||||
return;
|
||||
}
|
||||
|
||||
const range = ranges[0];
|
||||
const argStart = arg.getStart(sourceFile);
|
||||
if (range.end + 1 !== argStart && sourceFile.text.slice(range.end, argStart).indexOf("\n") === -1) {
|
||||
ctx.addFailureAtNode(arg, "There should be 1 space between an argument and its comment.");
|
||||
}
|
||||
}
|
||||
|
||||
function isTrivia(arg: ts.Expression): boolean {
|
||||
switch (arg.kind) {
|
||||
case ts.SyntaxKind.TrueKeyword:
|
||||
case ts.SyntaxKind.FalseKeyword:
|
||||
case ts.SyntaxKind.NullKeyword:
|
||||
return true;
|
||||
case ts.SyntaxKind.Identifier:
|
||||
return (arg as ts.Identifier).originalKeywordKind === ts.SyntaxKind.UndefinedKeyword;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user