Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/palantir/tslint into comp…
Browse files Browse the repository at this point in the history
…uted_property_names
  • Loading branch information
andy-hanson committed Dec 15, 2016
2 parents af13e4b + ddcd510 commit e30337b
Show file tree
Hide file tree
Showing 99 changed files with 534 additions and 296 deletions.
43 changes: 43 additions & 0 deletions docs/_data/rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,25 @@
"type": "functionality",
"typescriptOnly": false
},
{
"ruleName": "import-blacklist",
"description": "\nDisallows importing the specified modules directly via `import` and `require`.\nInstead only sub modules may be imported from that module.",
"rationale": "\nSome libraries allow importing their submodules instead of the entire module.\nThis is good practise as it avoids loading unused modules.",
"optionsDescription": "A list of blacklisted modules.",
"options": {
"type": "array",
"items": {
"type": "string"
},
"minLength": 1
},
"optionExamples": [
"true",
"[true, \"rxjs\", \"lodash\"]"
],
"type": "functionality",
"typescriptOnly": false
},
{
"ruleName": "indent",
"description": "Enforces indentation with tabs or spaces.",
Expand Down Expand Up @@ -642,6 +661,18 @@
"type": "typescript",
"typescriptOnly": true
},
{
"ruleName": "no-inferred-empty-object-type",
"description": "Disallow type inference of {} (empty object type) at function and constructor call sites",
"optionsDescription": "Not configurable.",
"options": null,
"optionExamples": [
"true"
],
"type": "functionality",
"typescriptOnly": true,
"requiresTypeInfo": true
},
{
"ruleName": "no-internal-module",
"description": "Disallows internal `module`",
Expand Down Expand Up @@ -1209,6 +1240,18 @@
"type": "style",
"typescriptOnly": false
},
{
"ruleName": "strict-boolean-expressions",
"description": "Usage of && or || operators should be with boolean operands and\nexpressions in If, Do, While and For statements should be of type boolean",
"optionsDescription": "Not configurable.",
"options": null,
"optionExamples": [
"true"
],
"type": "functionality",
"typescriptOnly": true,
"requiresTypeInfo": true
},
{
"ruleName": "switch-default",
"description": "Require a `default` case in all `switch` statements.",
Expand Down
32 changes: 32 additions & 0 deletions docs/rules/import-blacklist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
ruleName: import-blacklist
description: |-

Disallows importing the specified modules directly via `import` and `require`.
Instead only sub modules may be imported from that module.
rationale: |-

Some libraries allow importing their submodules instead of the entire module.
This is good practise as it avoids loading unused modules.
optionsDescription: A list of blacklisted modules.
options:
type: array
items:
type: string
minLength: 1
optionExamples:
- 'true'
- '[true, "rxjs", "lodash"]'
type: functionality
typescriptOnly: false
layout: rule
title: 'Rule: import-blacklist'
optionsJSON: |-
{
"type": "array",
"items": {
"type": "string"
},
"minLength": 1
}
---
14 changes: 14 additions & 0 deletions docs/rules/no-inferred-empty-object-type/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
ruleName: no-inferred-empty-object-type
description: 'Disallow type inference of {} (empty object type) at function and constructor call sites'
optionsDescription: Not configurable.
options: null
optionExamples:
- 'true'
type: functionality
typescriptOnly: true
requiresTypeInfo: true
layout: rule
title: 'Rule: no-inferred-empty-object-type'
optionsJSON: 'null'
---
16 changes: 16 additions & 0 deletions docs/rules/prefer-const/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
ruleName: prefer-const
description: Requires that variable declarations use `const` instead of `let` if possible.
descriptionDetails: |-

If a variable is only assigned to once when it is declared, it should be declared using 'const'
optionsDescription: Not configurable.
options: null
optionExamples:
- 'true'
type: maintainability
typescriptOnly: false
layout: rule
title: 'Rule: prefer-const'
optionsJSON: 'null'
---
16 changes: 16 additions & 0 deletions docs/rules/strict-boolean-expressions/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
ruleName: strict-boolean-expressions
description: |-
Usage of && or || operators should be with boolean operands and
expressions in If, Do, While and For statements should be of type boolean
optionsDescription: Not configurable.
options: null
optionExamples:
- 'true'
type: functionality
typescriptOnly: true
requiresTypeInfo: true
layout: rule
title: 'Rule: strict-boolean-expressions'
optionsJSON: 'null'
---
11 changes: 6 additions & 5 deletions docs/usage/library/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ var configuration = {

var options = {
formatter: "json",
configuration: configuration,
rulesDirectory: "customRules/", // can be an array of directories
formattersDirectory: "customFormatters/"
formattersDirectory: "customFormatters/",
fix: false
};

var Linter = require("tslint");
var Linter = require("tslint").Linter;
var fs = require("fs");
var contents = fs.readFileSync(fileName, "utf8");

var ll = new Linter(fileName, contents, options);
var result = ll.lint();
var linter = new Linter(options);
linter.lint(fileName, contents, configuration);
var result = linter.getResult();
```
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"verify": "npm-run-all clean compile lint test docs"
},
"dependencies": {
"babel-code-frame": "^6.16.0",
"babel-code-frame": "^6.20.0",
"colors": "^1.1.2",
"diff": "^3.0.1",
"findup-sync": "~0.3.0",
Expand All @@ -46,7 +46,7 @@
"update-notifier": "^1.0.2"
},
"devDependencies": {
"@types/babel-code-frame": "^6.16.0",
"@types/babel-code-frame": "^6.20.0",
"@types/chai": "^3.4.34",
"@types/colors": "^0.6.33",
"@types/diff": "0.0.31",
Expand All @@ -66,7 +66,7 @@
"rimraf": "^2.5.4",
"tslint": "latest",
"tslint-test-config-non-relative": "file:test/external/tslint-test-config-non-relative",
"typescript": "2.0.10"
"typescript": "2.1.4"
},
"peerDependencies": {
"typescript": ">=2.0.0"
Expand Down
4 changes: 2 additions & 2 deletions src/formatters/codeFrameFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

import {AbstractFormatter} from "../language/formatter/abstractFormatter";
import {IFormatterMetadata} from "../language/formatter/formatter";
import {RuleFailure} from "../language/rule/rule";
import { RuleFailure } from "../language/rule/rule";

import * as codeFrame from "babel-code-frame";
import codeFrame = require("babel-code-frame");
import * as colors from "colors";

import * as Utils from "../utils";
Expand Down
16 changes: 13 additions & 3 deletions src/language/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function scanAllTokens(scanner: ts.Scanner, callback: (s: ts.Scanner) =>
/**
* @returns true if any modifier kinds passed along exist in the given modifiers array
*/
export function hasModifier(modifiers: ts.ModifiersArray|undefined, ...modifierKinds: ts.SyntaxKind[]) {
export function hasModifier(modifiers: ts.ModifiersArray | undefined, ...modifierKinds: ts.SyntaxKind[]) {
if (modifiers === undefined || modifierKinds.length === 0) {
return false;
}
Expand Down Expand Up @@ -147,9 +147,19 @@ export function isNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags): boolean
/**
* Bitwise check for type flags.
*/
export function isTypeFlagSet(typ: ts.Type, flagToCheck: ts.TypeFlags): boolean {
export function isTypeFlagSet(type: ts.Type, flagToCheck: ts.TypeFlags): boolean {
/* tslint:disable:no-bitwise */
return (typ.flags & flagToCheck) !== 0;
return (type.flags & flagToCheck) !== 0;
/* tslint:enable:no-bitwise */
}

/**
* Bitwise check for object flags.
* Does not work with TypeScript 2.0.x
*/
export function isObjectFlagSet(objectType: ts.ObjectType, flagToCheck: ts.ObjectFlags): boolean {
/* tslint:disable:no-bitwise */
return (objectType.objectFlags & flagToCheck) !== 0;
/* tslint:enable:no-bitwise */
}

Expand Down
15 changes: 15 additions & 0 deletions src/language/walker/ruleWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ export class RuleWalker extends SyntaxWalker {
}
}

/** Add a failure with any arbitrary span. Prefer `addFailureAtNode` if possible. */
public addFailureAt(start: number, width: number, failure: string, fix?: Fix) {
this.addFailure(this.createFailure(start, width, failure, fix));
}

/** Like `addFailureAt` but uses start and end instead of start and width. */
public addFailureFromStartToEnd(start: number, end: number, failure: string, fix?: Fix) {
this.addFailureAt(start, end - start, failure, fix);
}

/** Add a failure using a node's span. */
public addFailureAtNode(node: ts.Node, failure: string, fix?: Fix) {
this.addFailureAt(node.getStart(), node.getWidth(), failure, fix);
}

public createReplacement(start: number, length: number, text: string): Replacement {
return new Replacement(start, length, text);
}
Expand Down
3 changes: 2 additions & 1 deletion src/linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ class Linter {
}

const { config } = ts.readConfigFile(configFile, ts.sys.readFile);
const parseConfigHost = {
const parseConfigHost: ts.ParseConfigHost = {
fileExists: fs.existsSync,
readDirectory: ts.sys.readDirectory,
readFile: (file) => fs.readFileSync(file, "utf8"),
useCaseSensitiveFileNames: true,
};
const parsed = ts.parseJsonConfigFileContent(config, parseConfigHost, projectDirectory);
Expand Down
3 changes: 1 addition & 2 deletions src/rules/adjacentOverloadSignaturesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ class AdjacentOverloadSignaturesWalker extends Lint.RuleWalker {
if (overload) {
const { name, key } = overload;
if (key in seen && lastKey !== key) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(),
Rule.FAILURE_STRING_FACTORY(name)));
this.addFailureAtNode(node, Rule.FAILURE_STRING_FACTORY(name)));
}
seen[key] = true;
lastKey = key;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/alignRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class AlignWalker extends Lint.RuleWalker {
for (let node of nodes.slice(1)) {
const curPos = getPosition(node);
if (curPos.line !== prevPos.line && curPos.character !== alignToColumn) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), kind + Rule.FAILURE_STRING_SUFFIX));
this.addFailureAtNode(node, kind + Rule.FAILURE_STRING_SUFFIX);
break;
}
prevPos = curPos;
Expand Down
6 changes: 3 additions & 3 deletions src/rules/arrayTypeRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ArrayTypeWalker extends Lint.RuleWalker {
// Delete the square brackets and replace with an angle bracket
this.createReplacement(typeName.getEnd() - parens, node.getEnd() - typeName.getEnd() + parens, ">"),
]);
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), failureString, fix));
this.addFailureAtNode(node, failureString, fix);
}

super.visitArrayType(node);
Expand All @@ -68,7 +68,7 @@ class ArrayTypeWalker extends Lint.RuleWalker {
const fix = new Lint.Fix(Rule.metadata.ruleName, [
this.createReplacement(node.getStart(), node.getWidth(), "any[]"),
]);
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), failureString, fix));
this.addFailureAtNode(node, failureString, fix);
} else if (typeArgs && typeArgs.length === 1 && (!this.hasOption(OPTION_ARRAY_SIMPLE) || this.isSimpleType(typeArgs[0]))) {
const type = typeArgs[0];
const typeStart = type.getStart();
Expand All @@ -81,7 +81,7 @@ class ArrayTypeWalker extends Lint.RuleWalker {
// Delete the last angle bracket and replace with square brackets
this.createReplacement(typeEnd, node.getEnd() - typeEnd, (parens ? ")" : "") + "[]"),
]);
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), failureString, fix));
this.addFailureAtNode(node, failureString, fix);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/rules/arrowParensRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import * as ts from "typescript";

import * as Lint from "../index";
import { hasModifier } from "../language/utils";

export class Rule extends Lint.Rules.AbstractRule {
/* tslint:disable:object-literal-sort-keys */
Expand Down Expand Up @@ -58,10 +59,10 @@ class ArrowParensWalker extends Lint.RuleWalker {
}

if ((firstToken.kind !== ts.SyntaxKind.OpenParenToken || lastToken.kind !== ts.SyntaxKind.CloseParenToken)
&& !isGenerics && node.flags !== ts.NodeFlags.Async) {
&& !isGenerics && !hasModifier(node.modifiers, ts.SyntaxKind.AsyncKeyword)) {

const fix = new Lint.Fix(Rule.metadata.ruleName, [new Lint.Replacement(position, width, `(${parameter.getText()})`)]);
this.addFailure(this.createFailure(position, width, Rule.FAILURE_STRING, fix));
this.addFailureAt(position, width, Rule.FAILURE_STRING, fix);
}
}
super.visitArrowFunction(node);
Expand Down
15 changes: 5 additions & 10 deletions src/rules/banRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class Rule extends Lint.Rules.AbstractRule {
ruleName: "ban",
description: "Bans the use of specific functions or global methods.",
optionsDescription: Lint.Utils.dedent`
A list of \`['object', 'method', 'optional explanation here']\` or \`['globalMethod']\` which ban \`object.method()\`
A list of \`['object', 'method', 'optional explanation here']\` or \`['globalMethod']\` which ban \`object.method()\`
or respectively \`globalMethod()\`.`,
options: {
type: "list",
Expand All @@ -36,7 +36,7 @@ export class Rule extends Lint.Rules.AbstractRule {
maxLength: 3,
},
},
optionExamples: [`[true, ["someGlobalMethod"], ["someObject", "someFunction"],
optionExamples: [`[true, ["someGlobalMethod"], ["someObject", "someFunction"],
["someObject", "otherFunction", "Optional explanation"]]`],
type: "functionality",
typescriptOnly: false,
Expand Down Expand Up @@ -99,12 +99,8 @@ export class BanFunctionWalker extends Lint.RuleWalker {
if (secondChild.kind === ts.SyntaxKind.DotToken) {
for (const bannedFunction of this.bannedFunctions) {
if (leftSideExpression === bannedFunction[0] && rightSideExpression === bannedFunction[1]) {
const failure = this.createFailure(
expression.getStart(),
expression.getWidth(),
Rule.FAILURE_STRING_FACTORY(`${leftSideExpression}.${rightSideExpression}`, bannedFunction[2]),
);
this.addFailure(failure);
const failure = Rule.FAILURE_STRING_FACTORY(`${leftSideExpression}.${rightSideExpression}`, bannedFunction[2]);
this.addFailureAtNode(expression, failure);
}
}
}
Expand All @@ -115,8 +111,7 @@ export class BanFunctionWalker extends Lint.RuleWalker {
if (expression.kind === ts.SyntaxKind.Identifier) {
const identifierName = (<ts.Identifier> expression).text;
if (this.bannedGlobalFunctions.indexOf(identifierName) !== -1) {
this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(),
Rule.FAILURE_STRING_FACTORY(`${identifierName}`)));
this.addFailureAtNode(expression, Rule.FAILURE_STRING_FACTORY(`${identifierName}`));
}

}
Expand Down
Loading

0 comments on commit e30337b

Please sign in to comment.