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

Commit

Permalink
Merge pull request #1756 from palantir/ad/master-into-next
Browse files Browse the repository at this point in the history
Prepare release v4.0.0-dev.3
  • Loading branch information
nchen63 authored Nov 23, 2016
2 parents 33478e8 + 96e1bef commit d7960b8
Show file tree
Hide file tree
Showing 49 changed files with 425 additions and 290 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
Change Log
===

v4.0.0-dev.3
---
* Include latest v4.0.2 changes

v4.0.2
---
* [enhancement] Don't exit when a rule can't be found. Print as a warning instead (#1771)
* [bugfix] Don't flag a property named as empty string as not needing quotes in an object literal (#1762)
* [bugfix] Report correct number of fixes done by --fix (#1767)
* [bugfix] Allow 3rd party apps to see exception when the config is invalid (#1764)
* [bugfix] Fix false positives and exceptions in `prefer-for-of` (#1758)
* [bugfix] Fix `adjacent-overload-signatures` false positive when a static function has the same name (#1772)

Thanks to our contributors!
* @gustavderdrache

v4.0.1
---
* [bugfix] Removed `no-unused-variable` rule from recommended config, as it was causing spurious deprecation warnings.

v4.0.0-dev.2
---
* Include latest v4.0.0 changes
Expand Down
33 changes: 16 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ TSLint supports:
- custom formatters (failure reporters)
- inline disabling / enabling of rules
- configuration presets (`tslint:latest`, `tslint-react`, etc.) & composition
- automatic fixing of formatting & style violations
- 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

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

#### Library

```javascript
const Linter = require("tslint");
const fs = require("fs");
```js
import { Linter } from "tslint";
import * as fs from "fs";

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

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.

```javascript
```js
const program = Linter.createProgram("tsconfig.json", "projectDir/");
const files = Linter.getFileNames(program);
const results = files.map(file => {
Expand Down Expand Up @@ -321,20 +322,20 @@ __Important conventions__:

Now, let us first write the rule in TypeScript:

```typescript
```ts
import * as ts from "typescript";
import * as Lint from "tslint";
import { Rules, RuleFailure, RuleWalker } from "tslint";

export class Rule extends Lint.Rules.AbstractRule {
export class Rule extends Rules.AbstractRule {
public static FAILURE_STRING = "import statement forbidden";

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
public apply(sourceFile: ts.SourceFile): RuleFailure[] {
return this.applyWithWalker(new NoImportsWalker(sourceFile, this.getOptions()));
}
}

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

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!

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

Final notes:

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

```typescript
import * as ts from "typescript";
import * as Lint from "tslint/lib/lint";
import { Formatters, RuleFailure } from "tslint";

export class Formatter extends Lint.Formatters.AbstractFormatter {
public format(failures: Lint.RuleFailure[]): string {
var failuresJSON = failures.map((failure: Lint.RuleFailure) => failure.toJson());
export class Formatter extends Formatters.AbstractFormatter {
public format(failures: RuleFailure[]): string {
var failuresJSON = failures.map((failure: RuleFailure) => failure.toJson());
return JSON.stringify(failuresJSON);
}
}
Expand Down Expand Up @@ -412,5 +413,3 @@ Creating a new release
4. Commit with message `Prepare release <version>`
5. Run `npm publish`
6. Create a git tag for the new release and push it ([see existing tags here](https://github.com/palantir/tslint/tags))

[0]: {{site.baseurl | append: "/usage/tslint-json/"}}
4 changes: 2 additions & 2 deletions docs/_data/rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@
},
{
"ruleName": "max-classes-per-file",
"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",
"description": "\nA file may not contain more than the specified number of classes",
"rationale": "\nEnsures that files have a single responsibility so that that classes each exist in their own files",
"optionsDescription": "\nThe one required argument is an integer indicating the maximum number of classes that can appear in a file.",
"options": {
Expand Down Expand Up @@ -850,7 +850,7 @@
},
{
"ruleName": "no-unused-variable",
"deprecationMessage": "Use the compiler options --noUnusedParameters and --noUnusedLocals instead.",
"deprecationMessage": "Use the tsc compiler options --noUnusedParameters and --noUnusedLocals instead.",
"description": "Disallows unused imports, variables, functions and private class members.",
"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.",
"options": {
Expand Down
7 changes: 5 additions & 2 deletions docs/_posts/2016-11-17-new-for-4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ TSLint 4.0 has been released! With this release comes a few exciting [changes][0
* [semicolon][7]
* [trailing-comma][8]

* **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.

* **TypeScript 2.0+ required**. This lets us deprecate/remove rules that are checked by the compiler. These rules now cause compilation errors:
* **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.

* **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`:
* no-duplicate-key
* no-unreachable
* no-unused-variable


* **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"`.

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


* **Other rules you might find handy**:
* [completed-docs][23]
* [cyclomatic-complexity][24]
Expand Down
2 changes: 1 addition & 1 deletion docs/develop/custom-formatters/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Just like [custom rules][0], additional formatters can also be supplied to TSLin

```ts
import * as ts from "typescript";
import * as Lint from "tslint/lib/lint";
import * as Lint from "tslint";

export class Formatter extends Lint.Formatters.AbstractFormatter {
public format(failures: Lint.RuleFailure[]): string {
Expand Down
18 changes: 9 additions & 9 deletions docs/develop/custom-rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ TSLint ships with a set of core rules that can be configured. However, users are
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.

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

Now, let us first write the rule in TypeScript:

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

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

// create a failure at the current position
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING, fix));
// create a failure at the current position
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING, fix));
```
---
Final notes:
Expand Down
3 changes: 1 addition & 2 deletions docs/rules/max-classes-per-file/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
ruleName: max-classes-per-file
description: |-

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

Ensures that files have a single responsibility so that that classes each exist in their own files
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/no-unused-variable/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
ruleName: no-unused-variable
deprecationMessage: Use the compiler options --noUnusedParameters and --noUnusedLocals instead.
deprecationMessage: Use the tsc compiler options --noUnusedParameters and --noUnusedLocals instead.
description: 'Disallows unused imports, variables, functions and private class members.'
optionsDescription: |-

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tslint",
"version": "4.0.0-dev.2",
"version": "4.0.0-dev.3",
"description": "An extensible static analysis linter for the TypeScript language",
"bin": {
"tslint": "./bin/tslint"
Expand Down
2 changes: 0 additions & 2 deletions src/configs/recommended.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ export const rules = {
"no-unsafe-finally": true,
"no-unused-expression": true,
"no-unused-new": true,
// deprecated as of v4.0
"no-unused-variable": false,
// disable this rule as it is very heavy performance-wise and not that useful
"no-use-before-declare": false,
"no-var-keyword": true,
Expand Down
15 changes: 3 additions & 12 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import findup = require("findup-sync");
import * as fs from "fs";
import * as path from "path";
import * as resolve from "resolve";
import { FatalError } from "./error";

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

Expand All @@ -32,16 +33,7 @@ export interface IConfigurationFile {
rules?: any;
}

/**
* Define `Error` here to avoid using `Error` from @types/node.
* Using the `node` version causes a compilation error when this code is used as an npm library if @types/node is not already imported.
*/
export interface Error {
message: string;
}

export interface IConfigurationLoadResult {
error?: Error;
path: string;
results?: IConfigurationFile;
}
Expand Down Expand Up @@ -119,11 +111,10 @@ export function findConfiguration(configFile: string, inputFilePath: string): IC

try {
loadResult.results = loadConfigurationFromPath(path);
return loadResult;
} catch (error) {
loadResult.error = error;
throw new FatalError(`Failed to load ${path}: ${error.message}`, error);
}

return loadResult;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/enableDisableRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class EnableDisableRulesWalker extends SkippableTokenAwareRuleWalker {
rulesList = commentTextParts[1].split(/\s+/).slice(1);

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

// potentially there were no items, so default to `all`.
rulesList = rulesList.length > 0 ? rulesList : ["all"];
Expand Down
40 changes: 40 additions & 0 deletions src/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @license
* Copyright 2016 Palantir Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Generic error typing for EcmaScript errors
* Define `Error` here to avoid using `Error` from @types/node.
* Using the `node` version causes a compilation error when this code is used as an npm library if @types/node is not already imported.
*/
export declare class Error {
public name?: string;
public message: string;
public stack?: string;
constructor(message?: string);
}

/**
* Used to exit the program and display a friendly message without the callstack.
*/
export class FatalError extends Error {
public static NAME = "FatalError";
constructor(public message: string, public innerError?: Error) {
super(message);
this.name = FatalError.NAME;
this.stack = new Error().stack;
}
}
5 changes: 2 additions & 3 deletions src/linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import * as ts from "typescript";

import {
DEFAULT_CONFIG,
IConfigurationFile,
findConfiguration,
findConfigurationPath,
getRelativePath,
getRulesDirectories,
IConfigurationFile,
loadConfigurationFromPath,
} from "./configuration";
import { EnableDisableRulesWalker } from "./enableDisableRules";
Expand All @@ -41,7 +41,7 @@ import { arrayify, dedent } from "./utils";
* Linter that can lint multiple files in consecutive runs.
*/
class Linter {
public static VERSION = "4.0.0-dev.2";
public static VERSION = "4.0.0-dev.3";

public static findConfiguration = findConfiguration;
public static findConfigurationPath = findConfigurationPath;
Expand Down Expand Up @@ -102,7 +102,6 @@ class Linter {
let fileFailures: RuleFailure[] = [];

if (this.options.fix) {
this.fixes = [];
for (let rule of enabledRules) {
let ruleFailures = this.applyRule(rule, sourceFile);
const fixes = ruleFailures.map((f) => f.getFix()).filter((f) => !!f);
Expand Down
Loading

0 comments on commit d7960b8

Please sign in to comment.