Skip to content

Commit d7960b8

Browse files
authored
Merge pull request palantir#1756 from palantir/ad/master-into-next
Prepare release v4.0.0-dev.3
2 parents 33478e8 + 96e1bef commit d7960b8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+425
-290
lines changed

CHANGELOG.md

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
Change Log
22
===
33

4+
v4.0.0-dev.3
5+
---
6+
* Include latest v4.0.2 changes
7+
8+
v4.0.2
9+
---
10+
* [enhancement] Don't exit when a rule can't be found. Print as a warning instead (#1771)
11+
* [bugfix] Don't flag a property named as empty string as not needing quotes in an object literal (#1762)
12+
* [bugfix] Report correct number of fixes done by --fix (#1767)
13+
* [bugfix] Allow 3rd party apps to see exception when the config is invalid (#1764)
14+
* [bugfix] Fix false positives and exceptions in `prefer-for-of` (#1758)
15+
* [bugfix] Fix `adjacent-overload-signatures` false positive when a static function has the same name (#1772)
16+
17+
Thanks to our contributors!
18+
* @gustavderdrache
19+
20+
v4.0.1
21+
---
22+
* [bugfix] Removed `no-unused-variable` rule from recommended config, as it was causing spurious deprecation warnings.
23+
424
v4.0.0-dev.2
525
---
626
* Include latest v4.0.0 changes

README.md

+16-17
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ TSLint supports:
1414
- custom formatters (failure reporters)
1515
- inline disabling / enabling of rules
1616
- configuration presets (`tslint:latest`, `tslint-react`, etc.) & composition
17+
- automatic fixing of formatting & style violations
1718
- integration with [msbuild](https://github.com/joshuakgoldberg/tslint.msbuild), [grunt](https://github.com/palantir/grunt-tslint), [gulp](https://github.com/panuhorsmalahti/gulp-tslint), [atom](https://github.com/AtomLinter/linter-tslint), [eclipse](https://github.com/palantir/eclipse-tslint), [emacs](http://flycheck.org), [sublime](https://packagecontrol.io/packages/SublimeLinter-contrib-tslint), [vim](https://github.com/scrooloose/syntastic), [visual studio](https://visualstudiogallery.msdn.microsoft.com/6edc26d4-47d8-4987-82ee-7c820d79be1d), [vscode](https://marketplace.visualstudio.com/items?itemName=eg2.tslint), [webstorm](https://www.jetbrains.com/webstorm/help/tslint.html), and more
1819

1920
Table of Contents
@@ -115,7 +116,7 @@ Options:
115116
```
116117
-c, --config configuration file
117118
-e, --exclude exclude globs from path expansion
118-
--fix Fixes linting errors for select rules. This may overwrite linted files
119+
--fix fixes linting errors for select rules (this may overwrite linted files)
119120
--force return status code 0 even if there are lint errors
120121
-h, --help display detailed help
121122
-i, --init generate a tslint.json config file in the current working directory
@@ -213,9 +214,9 @@ tslint accepts the following command-line options:
213214

214215
#### Library
215216

216-
```javascript
217-
const Linter = require("tslint");
218-
const fs = require("fs");
217+
```js
218+
import { Linter } from "tslint";
219+
import * as fs from "fs";
219220

220221
const fileName = "Specify file name";
221222
const configuration = {
@@ -240,7 +241,7 @@ const result = linter.lint();
240241

241242
To enable rules that work with the type checker, a TypeScript program object must be passed to the linter when using the programmatic API. Helper functions are provided to create a program from a `tsconfig.json` file. A project directory can be specified if project files do not lie in the same directory as the `tsconfig.json` file.
242243

243-
```javascript
244+
```js
244245
const program = Linter.createProgram("tsconfig.json", "projectDir/");
245246
const files = Linter.getFileNames(program);
246247
const results = files.map(file => {
@@ -321,20 +322,20 @@ __Important conventions__:
321322

322323
Now, let us first write the rule in TypeScript:
323324

324-
```typescript
325+
```ts
325326
import * as ts from "typescript";
326-
import * as Lint from "tslint";
327+
import { Rules, RuleFailure, RuleWalker } from "tslint";
327328

328-
export class Rule extends Lint.Rules.AbstractRule {
329+
export class Rule extends Rules.AbstractRule {
329330
public static FAILURE_STRING = "import statement forbidden";
330331

331-
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
332+
public apply(sourceFile: ts.SourceFile): RuleFailure[] {
332333
return this.applyWithWalker(new NoImportsWalker(sourceFile, this.getOptions()));
333334
}
334335
}
335336

336337
// The walker takes care of all the work.
337-
class NoImportsWalker extends Lint.RuleWalker {
338+
class NoImportsWalker extends RuleWalker {
338339
public visitImportDeclaration(node: ts.ImportDeclaration) {
339340
// create a failure at the current position
340341
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
@@ -355,7 +356,7 @@ tsc --noImplicitAny noImportsRule.ts
355356

356357
Then, if using the CLI, provide the directory that contains this rule as an option to `--rules-dir`. If using TSLint as a library or via `grunt-tslint`, the `options` hash must contain `"rulesDirectory": "..."`. If you run the linter, you'll see that we have now successfully banned all import statements via TSLint!
357358

358-
Finally, enable each custom rule in your [`tslint.json` config file][0] config file.
359+
Finally, enable each custom rule in your [`tslint.json` config file](https://palantir.github.io/tslint/usage/tslint-json/) config file.
359360

360361
Final notes:
361362

@@ -370,11 +371,11 @@ Just like rules, additional formatters can also be supplied to TSLint via `--for
370371

371372
```typescript
372373
import * as ts from "typescript";
373-
import * as Lint from "tslint/lib/lint";
374+
import { Formatters, RuleFailure } from "tslint";
374375

375-
export class Formatter extends Lint.Formatters.AbstractFormatter {
376-
public format(failures: Lint.RuleFailure[]): string {
377-
var failuresJSON = failures.map((failure: Lint.RuleFailure) => failure.toJson());
376+
export class Formatter extends Formatters.AbstractFormatter {
377+
public format(failures: RuleFailure[]): string {
378+
var failuresJSON = failures.map((failure: RuleFailure) => failure.toJson());
378379
return JSON.stringify(failuresJSON);
379380
}
380381
}
@@ -412,5 +413,3 @@ Creating a new release
412413
4. Commit with message `Prepare release <version>`
413414
5. Run `npm publish`
414415
6. Create a git tag for the new release and push it ([see existing tags here](https://github.com/palantir/tslint/tags))
415-
416-
[0]: {{site.baseurl | append: "/usage/tslint-json/"}}

docs/_data/rules.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@
296296
},
297297
{
298298
"ruleName": "max-classes-per-file",
299-
"description": "\nA file may not contain more than the specified number of classes \nif the file name does not match the \"ignore-filename-pattern\" option",
299+
"description": "\nA file may not contain more than the specified number of classes",
300300
"rationale": "\nEnsures that files have a single responsibility so that that classes each exist in their own files",
301301
"optionsDescription": "\nThe one required argument is an integer indicating the maximum number of classes that can appear in a file.",
302302
"options": {
@@ -850,7 +850,7 @@
850850
},
851851
{
852852
"ruleName": "no-unused-variable",
853-
"deprecationMessage": "Use the compiler options --noUnusedParameters and --noUnusedLocals instead.",
853+
"deprecationMessage": "Use the tsc compiler options --noUnusedParameters and --noUnusedLocals instead.",
854854
"description": "Disallows unused imports, variables, functions and private class members.",
855855
"optionsDescription": "\nThree optional arguments may be optionally provided:\n\n* `\"check-parameters\"` disallows unused function and constructor parameters.\n * NOTE: this option is experimental and does not work with classes\n that use abstract method declarations, among other things.\n* `\"react\"` relaxes the rule for a namespace import named `React`\n(from either the module `\"react\"` or `\"react/addons\"`).\nAny JSX expression in the file will be treated as a usage of `React`\n(because it expands to `React.createElement `).\n* `{\"ignore-pattern\": \"pattern\"}` where pattern is a case-sensitive regexp.\nVariable names that match the pattern will be ignored.",
856856
"options": {

docs/_posts/2016-11-17-new-for-4.0.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ TSLint 4.0 has been released! With this release comes a few exciting [changes][0
1515
* [semicolon][7]
1616
* [trailing-comma][8]
1717

18-
* **Linting `.js` files**. *A much-requested feature from our community*. Simplify your toolset by running the same rules you know and love on your .js and .jsx files. Just add a `jsRules` [section][9] to your `tslint.json` file, and TSLint will your JavaScript files.
1918

20-
* **TypeScript 2.0+ required**. This lets us deprecate/remove rules that are checked by the compiler. These rules now cause compilation errors:
19+
* **Linting `.js` files**. *A much-requested feature from our community*. Simplify your toolset by running the same rules you know and love on your .js and .jsx files. Just add a `jsRules` [section][9] to your `tslint.json` file, and TSLint will lint your JavaScript files.
20+
21+
* **TypeScript 2.0+ required**. This lets us deprecate/remove rules that are checked by the compiler. Problematic code that once violated these rules now cause compilation errors in `tsc`:
2122
* no-duplicate-key
2223
* no-unreachable
2324
* no-unused-variable
2425

26+
2527
* **Node.js API Change**. [Moved and renamed][11] some things to make more sense. Get it all when you use `import * as TSLint from "tslint"`.
2628

2729
* **[Recommended Rules Updated][12]**
@@ -36,6 +38,7 @@ TSLint 4.0 has been released! With this release comes a few exciting [changes][0
3638
* [ordered-imports][21]
3739
* [prefer-for-of][22]
3840

41+
3942
* **Other rules you might find handy**:
4043
* [completed-docs][23]
4144
* [cyclomatic-complexity][24]

docs/develop/custom-formatters/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Just like [custom rules][0], additional formatters can also be supplied to TSLin
88

99
```ts
1010
import * as ts from "typescript";
11-
import * as Lint from "tslint/lib/lint";
11+
import * as Lint from "tslint";
1212

1313
export class Formatter extends Lint.Formatters.AbstractFormatter {
1414
public format(failures: Lint.RuleFailure[]): string {

docs/develop/custom-rules/index.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ TSLint ships with a set of core rules that can be configured. However, users are
88
Let us take the example of how to write a new rule to forbid all import statements (you know, *for science*). Let us name the rule file `noImportsRule.ts`. Rules are referenced in `tslint.json` with their kebab-cased identifer, so `"no-imports": true` would configure the rule.
99

1010
__Important conventions__:
11-
* Rule identifiers are always kebab-cased.
12-
* Rule files are always camel-cased (`camelCasedRule.ts`).
13-
* Rule files *must* contain the suffix `Rule`.
14-
* The exported class must always be named `Rule` and extend from `Lint.Rules.AbstractRule`.
11+
- Rule identifiers are always kebab-cased.
12+
- Rule files are always camel-cased (`camelCasedRule.ts`).
13+
- Rule files *must* contain the suffix `Rule`.
14+
- The exported class must always be named `Rule` and extend from `Lint.Rules.AbstractRule`.
1515

1616
Now, let us first write the rule in TypeScript:
1717

@@ -58,12 +58,12 @@ Now that you're written a rule to detect problems, let's modify it to *fix* them
5858
Instantiate a `Fix` object and pass it in as an argument to `addFailure`. This snippet replaces the offending import statement with an empty string:
5959

6060
```typescript
61-
// create a fixer for this failure
62-
const replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "");
63-
const fix = new Lint.Fix("no-imports", [replacement]);
61+
// create a fixer for this failure
62+
const replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "");
63+
const fix = new Lint.Fix("no-imports", [replacement]);
6464

65-
// create a failure at the current position
66-
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING, fix));
65+
// create a failure at the current position
66+
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING, fix));
6767
```
6868
---
6969
Final notes:

docs/rules/max-classes-per-file/index.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
ruleName: max-classes-per-file
33
description: |-
44

5-
A file may not contain more than the specified number of classes
6-
if the file name does not match the "ignore-filename-pattern" option
5+
A file may not contain more than the specified number of classes
76
rationale: |-
87

98
Ensures that files have a single responsibility so that that classes each exist in their own files

docs/rules/no-unused-variable/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
ruleName: no-unused-variable
3-
deprecationMessage: Use the compiler options --noUnusedParameters and --noUnusedLocals instead.
3+
deprecationMessage: Use the tsc compiler options --noUnusedParameters and --noUnusedLocals instead.
44
description: 'Disallows unused imports, variables, functions and private class members.'
55
optionsDescription: |-
66

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tslint",
3-
"version": "4.0.0-dev.2",
3+
"version": "4.0.0-dev.3",
44
"description": "An extensible static analysis linter for the TypeScript language",
55
"bin": {
66
"tslint": "./bin/tslint"

src/configs/recommended.ts

-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ export const rules = {
7171
"no-unsafe-finally": true,
7272
"no-unused-expression": true,
7373
"no-unused-new": true,
74-
// deprecated as of v4.0
75-
"no-unused-variable": false,
7674
// disable this rule as it is very heavy performance-wise and not that useful
7775
"no-use-before-declare": false,
7876
"no-var-keyword": true,

src/configuration.ts

+3-12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import findup = require("findup-sync");
1919
import * as fs from "fs";
2020
import * as path from "path";
2121
import * as resolve from "resolve";
22+
import { FatalError } from "./error";
2223

2324
import {arrayify, objectify, stripComments} from "./utils";
2425

@@ -32,16 +33,7 @@ export interface IConfigurationFile {
3233
rules?: any;
3334
}
3435

35-
/**
36-
* Define `Error` here to avoid using `Error` from @types/node.
37-
* Using the `node` version causes a compilation error when this code is used as an npm library if @types/node is not already imported.
38-
*/
39-
export interface Error {
40-
message: string;
41-
}
42-
4336
export interface IConfigurationLoadResult {
44-
error?: Error;
4537
path: string;
4638
results?: IConfigurationFile;
4739
}
@@ -119,11 +111,10 @@ export function findConfiguration(configFile: string, inputFilePath: string): IC
119111

120112
try {
121113
loadResult.results = loadConfigurationFromPath(path);
114+
return loadResult;
122115
} catch (error) {
123-
loadResult.error = error;
116+
throw new FatalError(`Failed to load ${path}: ${error.message}`, error);
124117
}
125-
126-
return loadResult;
127118
}
128119

129120
/**

src/enableDisableRules.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export class EnableDisableRulesWalker extends SkippableTokenAwareRuleWalker {
7373
rulesList = commentTextParts[1].split(/\s+/).slice(1);
7474

7575
// remove empty items and potential comment end.
76-
rulesList = rulesList.filter(item => !!item && item.indexOf("*/") === -1);
76+
rulesList = rulesList.filter((item) => !!item && item.indexOf("*/") === -1);
7777

7878
// potentially there were no items, so default to `all`.
7979
rulesList = rulesList.length > 0 ? rulesList : ["all"];

src/error.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @license
3+
* Copyright 2016 Palantir Technologies, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/**
19+
* Generic error typing for EcmaScript errors
20+
* Define `Error` here to avoid using `Error` from @types/node.
21+
* Using the `node` version causes a compilation error when this code is used as an npm library if @types/node is not already imported.
22+
*/
23+
export declare class Error {
24+
public name?: string;
25+
public message: string;
26+
public stack?: string;
27+
constructor(message?: string);
28+
}
29+
30+
/**
31+
* Used to exit the program and display a friendly message without the callstack.
32+
*/
33+
export class FatalError extends Error {
34+
public static NAME = "FatalError";
35+
constructor(public message: string, public innerError?: Error) {
36+
super(message);
37+
this.name = FatalError.NAME;
38+
this.stack = new Error().stack;
39+
}
40+
}

src/linter.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ import * as ts from "typescript";
2020

2121
import {
2222
DEFAULT_CONFIG,
23-
IConfigurationFile,
2423
findConfiguration,
2524
findConfigurationPath,
2625
getRelativePath,
2726
getRulesDirectories,
27+
IConfigurationFile,
2828
loadConfigurationFromPath,
2929
} from "./configuration";
3030
import { EnableDisableRulesWalker } from "./enableDisableRules";
@@ -41,7 +41,7 @@ import { arrayify, dedent } from "./utils";
4141
* Linter that can lint multiple files in consecutive runs.
4242
*/
4343
class Linter {
44-
public static VERSION = "4.0.0-dev.2";
44+
public static VERSION = "4.0.0-dev.3";
4545

4646
public static findConfiguration = findConfiguration;
4747
public static findConfigurationPath = findConfigurationPath;
@@ -102,7 +102,6 @@ class Linter {
102102
let fileFailures: RuleFailure[] = [];
103103

104104
if (this.options.fix) {
105-
this.fixes = [];
106105
for (let rule of enabledRules) {
107106
let ruleFailures = this.applyRule(rule, sourceFile);
108107
const fixes = ruleFailures.map((f) => f.getFix()).filter((f) => !!f);

0 commit comments

Comments
 (0)