Skip to content

Commit 1cd016b

Browse files
committed
Boolean trivia rule
1 parent 7813121 commit 1cd016b

3 files changed

Lines changed: 54 additions & 2 deletions

File tree

Jakefile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,8 @@ var tslintRuleDir = "scripts/tslint";
774774
var tslintRules = ([
775775
"nextLineRule",
776776
"noInferrableTypesRule",
777-
"noNullRule"
777+
"noNullRule",
778+
"booleanTriviaRule"
778779
]);
779780
var tslintRulesFiles = tslintRules.map(function(p) {
780781
return path.join(tslintRuleDir, p + ".ts");
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/// <reference path="../../node_modules/tslint/typings/typescriptServices.d.ts" />
2+
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
3+
4+
5+
export class Rule extends Lint.Rules.AbstractRule {
6+
public static FAILURE_STRING_FACTORY = (name: string, currently: string) => `Tag boolean argument as '${name}' (currently '${currently}')`;
7+
8+
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
9+
const program = ts.createProgram([sourceFile.fileName], Lint.createCompilerOptions());
10+
const checker = program.getTypeChecker();
11+
return this.applyWithWalker(new BooleanTriviaWalker(checker, program.getSourceFile(sourceFile.fileName), this.getOptions()));
12+
}
13+
}
14+
15+
class BooleanTriviaWalker extends Lint.RuleWalker {
16+
constructor(private checker: ts.TypeChecker, file: ts.SourceFile, opts: Lint.IOptions) {
17+
super(file, opts);
18+
}
19+
20+
visitCallExpression(node: ts.CallExpression) {
21+
super.visitCallExpression(node);
22+
if (node.arguments) {
23+
const targetCallSignature = this.checker.getResolvedSignature(node);
24+
if (!!targetCallSignature) {
25+
const targetParameters = targetCallSignature.getParameters();
26+
const source = this.getSourceFile();
27+
for (let index = 0; index < targetParameters.length; index++) {
28+
const param = targetParameters[index];
29+
const arg = node.arguments[index];
30+
if (!(arg && param)) continue;
31+
32+
const argType = this.checker.getContextualType(arg);
33+
if (argType && (argType.getFlags() & ts.TypeFlags.Boolean)) {
34+
if (arg.kind !== ts.SyntaxKind.TrueKeyword && arg.kind !== ts.SyntaxKind.FalseKeyword) {
35+
continue;
36+
}
37+
let triviaContent: string;
38+
const ranges = ts.getLeadingCommentRanges(arg.getFullText(), 0);
39+
if (ranges && ranges.length === 1 && ranges[0].kind === ts.SyntaxKind.MultiLineCommentTrivia) {
40+
triviaContent = arg.getFullText().slice(ranges[0].pos + 2, ranges[0].end - 2); //+/-2 to remove /**/
41+
}
42+
if (triviaContent !== param.getName()) {
43+
this.addFailure(this.createFailure(arg.getStart(source), arg.getWidth(source), Rule.FAILURE_STRING_FACTORY(param.getName(), triviaContent)));
44+
}
45+
}
46+
}
47+
}
48+
}
49+
}
50+
}

tslint.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"no-internal-module": true,
4040
"no-trailing-whitespace": true,
4141
"no-inferrable-types": true,
42-
"no-null": true
42+
"no-null": true,
43+
"boolean-trivia": true
4344
}
4445
}

0 commit comments

Comments
 (0)