mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-29 14:04:20 -05:00
Add tslint rules for #3994
This commit is contained in:
63
scripts/tslint/nextLineRule.ts
Normal file
63
scripts/tslint/nextLineRule.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/// <reference path="../../lib/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
|
||||
const OPTION_CATCH = "check-catch";
|
||||
const OPTION_ELSE = "check-else";
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static CATCH_FAILURE_STRING = "'catch' should be on the line following the previous block's ending curly brace";
|
||||
public static ELSE_FAILURE_STRING = "'else' should be on the line following the previous block's ending curly brace";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new NextLineWalker(sourceFile, this.getOptions()));
|
||||
}
|
||||
}
|
||||
|
||||
class NextLineWalker extends Lint.RuleWalker {
|
||||
public visitIfStatement(node: ts.IfStatement) {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const thenStatement = node.thenStatement;
|
||||
|
||||
const elseStatement = node.elseStatement;
|
||||
if (!!elseStatement) {
|
||||
// find the else keyword
|
||||
const elseKeyword = getFirstChildOfKind(node, ts.SyntaxKind.ElseKeyword);
|
||||
if (this.hasOption(OPTION_ELSE) && !!elseKeyword) {
|
||||
const thenStatementEndLoc = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd());
|
||||
const elseKeywordLoc = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart());
|
||||
if (thenStatementEndLoc.line !== (elseKeywordLoc.line - 1)) {
|
||||
const failure = this.createFailure(elseKeyword.getStart(), elseKeyword.getWidth(), Rule.ELSE_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.visitIfStatement(node);
|
||||
}
|
||||
|
||||
public visitTryStatement(node: ts.TryStatement) {
|
||||
const sourceFile = node.getSourceFile();
|
||||
const catchClause = node.catchClause;
|
||||
|
||||
// "visit" try block
|
||||
const tryKeyword = node.getChildAt(0);
|
||||
const tryBlock = node.tryBlock;
|
||||
const tryOpeningBrace = tryBlock.getChildAt(0);
|
||||
|
||||
if (this.hasOption(OPTION_CATCH) && !!catchClause) {
|
||||
const tryClosingBrace = node.tryBlock.getChildAt(node.tryBlock.getChildCount() - 1);
|
||||
const catchKeyword = catchClause.getChildAt(0);
|
||||
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
|
||||
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart());
|
||||
if (tryClosingBraceLoc.line !== (catchKeywordLoc.line - 1)) {
|
||||
const failure = this.createFailure(catchKeyword.getStart(), catchKeyword.getWidth(), Rule.CATCH_FAILURE_STRING);
|
||||
this.addFailure(failure);
|
||||
}
|
||||
}
|
||||
super.visitTryStatement(node);
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstChildOfKind(node: ts.Node, kind: ts.SyntaxKind) {
|
||||
return node.getChildren().filter((child) => child.kind === kind)[0];
|
||||
}
|
||||
32
scripts/tslint/noInferrableTypesRule.ts
Normal file
32
scripts/tslint/noInferrableTypesRule.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/// <reference path="../../lib/typescriptServices.d.ts" />
|
||||
/// <reference path="../../node_modules/tslint/lib/tslint.d.ts" />
|
||||
|
||||
|
||||
export class Rule extends Lint.Rules.AbstractRule {
|
||||
public static FAILURE_STRING = "LHS type inferred by RHS expression, remove type annotation";
|
||||
|
||||
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
|
||||
const program = ts.createProgram([sourceFile.fileName], Lint.createCompilerOptions());
|
||||
return this.applyWithWalker(new InferrableTypeWalker(sourceFile, this.getOptions(), program));
|
||||
}
|
||||
}
|
||||
|
||||
class InferrableTypeWalker extends Lint.RuleWalker {
|
||||
constructor(file: ts.SourceFile, opts: Lint.IOptions, private program: ts.Program) {
|
||||
super(program.getSourceFile(file.fileName), opts);
|
||||
}
|
||||
|
||||
visitVariableStatement(node: ts.VariableStatement) {
|
||||
node.declarationList.declarations.forEach(e => {
|
||||
if (
|
||||
(!!e.type) &&
|
||||
(!!e.initializer) &&
|
||||
(this.program.getTypeChecker().getTypeAtLocation(e.type) === this.program.getTypeChecker().getContextualType(e.initializer))
|
||||
) {
|
||||
this.addFailure(this.createFailure(e.type.getStart(), e.type.getWidth(), Rule.FAILURE_STRING));
|
||||
}
|
||||
});
|
||||
|
||||
super.visitVariableStatement(node);
|
||||
}
|
||||
}
|
||||
7
scripts/tslint/tsconfig.json
Normal file
7
scripts/tslint/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": true,
|
||||
"module": "commonjs",
|
||||
"outDir": "../../built/local/tslint"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user