UNPKG

2.28 kBPlain TextView Raw
1import * as ts from 'typescript';
2import * as Lint from 'tslint';
3
4import { ErrorTolerantWalker } from './utils/ErrorTolerantWalker';
5import { ExtendedMetadata } from './utils/ExtendedMetadata';
6
7export const FAILURE_STRING: string = 'Try-catch blocks must be at the top of the scope';
8
9/**
10 * Implementation of the newspaper-order rule.
11 */
12export class Rule extends Lint.Rules.AbstractRule {
13 public static metadata: ExtendedMetadata = {
14 ruleName: 'try-catch-first',
15 type: 'maintainability',
16 description:
17 'Try-catch blocks must be first within the scope. ' +
18 'Try-catch blocks are transactions and should leave your program in a consistent state, no matter what happens in the try.',
19 options: null,
20 optionsDescription: '',
21 typescriptOnly: true,
22 issueClass: 'Non-SDL',
23 issueType: 'Warning',
24 severity: 'Important',
25 level: 'Opportunity for Excellence',
26 group: 'Correctness',
27 recommendation: 'true,',
28 commonWeaknessEnumeration: '',
29 };
30
31 public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
32 return this.applyWithWalker(new TryCatchFirstRuleWalker(sourceFile, this.getOptions()));
33 }
34}
35
36class TryCatchFirstRuleWalker extends ErrorTolerantWalker {
37 private scopeKinds: ts.SyntaxKind[] = [
38 ts.SyntaxKind.FunctionDeclaration,
39 ts.SyntaxKind.ArrowFunction,
40 ts.SyntaxKind.SourceFile,
41 ts.SyntaxKind.MethodDeclaration,
42 ts.SyntaxKind.GetAccessor,
43 ts.SyntaxKind.SetAccessor,
44 ];
45
46 protected visitTryStatement(node: ts.TryStatement): void {
47 this.checkAndReport(node);
48 super.visitTryStatement(node);
49 }
50
51 private checkAndReport(node: ts.TryStatement) {
52 const block = node.parent;
53 const { parent } = block;
54 // console.log('checkAndReport', block, parent); // tslint:disable-line no-console
55 const isFirst = this.scopeKinds.indexOf((parent || block).kind) !== -1;
56 if (!isFirst) {
57 const failureMessage = this.makeFailureMessage();
58 this.addFailureAt(node.getStart(), node.getWidth(), failureMessage);
59 }
60 }
61
62 private makeFailureMessage(): string {
63 return FAILURE_STRING;
64 }
65}