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' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason Killian committed Apr 11, 2016
2 parents 9a2dcdf + cc505ee commit 3cd1b52
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 22 deletions.
7 changes: 0 additions & 7 deletions .travis.yml

This file was deleted.

4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Change Log
===

v3.7.1
---
* Stable release containing changes from the last dev release

v3.7.0-dev.2
---
* [bugfix] Improve handling of paths provided via the -c CLI option (#1083)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[![NPM version](https://badge.fury.io/js/tslint.svg)](http://badge.fury.io/js/tslint)
[![Downloads](http://img.shields.io/npm/dm/tslint.svg)](https://npmjs.org/package/tslint)
[![Linux Build Status](https://travis-ci.org/palantir/tslint.svg?branch=master)](https://travis-ci.org/palantir/tslint)
[![Circle CI](https://circleci.com/gh/palantir/tslint.svg?style=svg)](https://circleci.com/gh/palantir/tslint)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/palantir/tslint?svg=true&branch=master)](https://ci.appveyor.com/project/ashwinr/tslint)
[![Join the chat at https://gitter.im/palantir/tslint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/palantir/tslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Expand All @@ -14,7 +14,7 @@ Supports:
- custom rules
- custom formatters
- inline disabling / enabling of rules
- 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), [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), [webstorm](https://www.jetbrains.com/webstorm/help/tslint.html), and more
- 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), [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
3 changes: 3 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
pre:
- case $CIRCLE_NODE_INDEX in 0) nvm use 0.10 ;; 1) nvm use 0.12 ;; 2) nvm use 4.2 ;; 3) nvm use 5.5 ;; esac
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"dependencies": {
"colors": "^1.1.2",
"diff": "^2.2.1",
"findup-sync": "~0.2.1",
"findup-sync": "~0.4.0",
"glob": "^6.0.1",
"optimist": "~0.6.0",
"path-is-absolute": "^1.0.0",
Expand Down
17 changes: 11 additions & 6 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,35 +83,35 @@ export function findConfiguration(configFile: string, inputFilePath: string): IC
* the location of the config file is not known and you want to search for one.
* @param inputFilePath A path to the current file being linted. This is the starting location
* of the search for a configuration.
* @returns A path to a tslint.json file, a path to a package.json file with a tslintConfig field
* @returns An absolute path to a tslint.json file, a path to a package.json file with a tslintConfig field
* or undefined if neither can be found.
*/
export function findConfigurationPath(suppliedConfigFilePath: string, inputFilePath: string) {
if (suppliedConfigFilePath != null) {
if (!fs.existsSync(suppliedConfigFilePath)) {
throw new Error(`Could not find config file at: ${path.resolve(suppliedConfigFilePath)}`);
} else {
return suppliedConfigFilePath;
return path.resolve(suppliedConfigFilePath);
}
} else {
// search for tslint.json from input file location
let configFilePath = findup(CONFIG_FILENAME, { cwd: inputFilePath, nocase: true });
if (configFilePath != null && fs.existsSync(configFilePath)) {
return configFilePath;
return path.resolve(configFilePath);
}

// search for package.json with tslintConfig property
configFilePath = findup("package.json", { cwd: inputFilePath, nocase: true });
if (configFilePath != null && require(configFilePath).tslintConfig != null) {
return configFilePath;
return path.resolve(configFilePath);
}

// search for tslint.json in home directory
const homeDir = getHomeDir();
if (homeDir != null) {
configFilePath = path.join(homeDir, CONFIG_FILENAME);
if (fs.existsSync(configFilePath)) {
return configFilePath;
return path.resolve(configFilePath);
}
}

Expand All @@ -121,7 +121,12 @@ export function findConfigurationPath(suppliedConfigFilePath: string, inputFileP
}

/**
* @returns a configuration object for TSLint loaded form the file at configFilePath
* Used Node semantics to load a configuration file given configFilePath.
* For example:
* '/path/to/config' will be treated as an absolute path
* './path/to/config' will be treated as a relative path
* 'path/to/config' will attempt to load a to/config file inside a node module named path
* @returns a configuration object for TSLint loaded from the file at configFilePath
*/
export function loadConfigurationFromPath(configFilePath: string): IConfigurationFile {
if (configFilePath == null) {
Expand Down
9 changes: 8 additions & 1 deletion src/rules/noInternalModuleRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class NoInternalModuleWalker extends Lint.RuleWalker {
// for external modules, node.name.kind will be a LiteralExpression instead of Identifier
return !Lint.isNodeFlagSet(node, ts.NodeFlags.Namespace)
&& !isNestedDeclaration(node)
&& node.name.kind === ts.SyntaxKind.Identifier;
&& node.name.kind === ts.SyntaxKind.Identifier
&& !isGlobalAugmentation(node);
}
}

Expand All @@ -49,3 +50,9 @@ function isNestedDeclaration(node: ts.ModuleDeclaration) {
// nodes
return node.name.pos === node.pos;
}

function isGlobalAugmentation(node: ts.ModuleDeclaration) {
// augmenting global uses a sepcial syntax that is allowed
// see https://github.com/Microsoft/TypeScript/pull/6213
return node.name.kind === ts.SyntaxKind.Identifier && node.name.text === "global";
}
26 changes: 23 additions & 3 deletions src/rules/noUnusedExpressionRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ class NoUnusedExpressionWalker extends Lint.RuleWalker {
const isValidStandaloneExpression = kind === ts.SyntaxKind.DeleteExpression
|| kind === ts.SyntaxKind.YieldExpression
|| kind === ts.SyntaxKind.AwaitExpression;
const isValidStringExpression = kind === ts.SyntaxKind.StringLiteral
&& (expression.getText() === '"use strict"' || expression.getText() === "'use strict'");

if (!isValidStandaloneExpression && !isValidStringExpression) {
if (!isValidStandaloneExpression && !isDirective(node)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
}
Expand Down Expand Up @@ -119,3 +117,25 @@ class NoUnusedExpressionWalker extends Lint.RuleWalker {
this.expressionIsUnused = firstExpressionIsUnused || secondExpressionIsUnused;
}
}

function isDirective(node: ts.Node, checkPreviousSiblings = true): boolean {
const { parent } = node;
const grandParentKind = parent.parent == null ? null : parent.parent.kind;
const isStringExpression = node.kind === ts.SyntaxKind.ExpressionStatement
&& (node as ts.ExpressionStatement).expression.kind === ts.SyntaxKind.StringLiteral;
const parentIsSourceFile = parent.kind === ts.SyntaxKind.SourceFile;
const parentIsFunctionBody = parent.kind === ts.SyntaxKind.Block
&& [ts.SyntaxKind.ArrowFunction, ts.SyntaxKind.FunctionExpression, ts.SyntaxKind.FunctionDeclaration].indexOf(grandParentKind) > -1;

if (!(parentIsSourceFile || parentIsFunctionBody) || !isStringExpression) {
return false;
}

if (checkPreviousSiblings) {
const siblings: ts.Node[] = [];
ts.forEachChild(node.parent, child => { siblings.push(child); });
return siblings.slice(0, siblings.indexOf(node)).every((n) => isDirective(n, false));
} else {
return true;
}
}
3 changes: 3 additions & 0 deletions test/rules/no-internal-module/test.ts.lint
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace foo {
}

// valid, special syntax for augmenting global
declare global { }

module bar {
~~~~~~~~~~~~
}
Expand Down
21 changes: 19 additions & 2 deletions test/rules/no-unused-expression/test.ts.lint
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
"use strict";
'use asm';
"ngInject";
'';

function fun1() {
"use strict";
'someOtherDirective';
return 0;
}

(function() { "directive";
'foo'
'directive2'
console.log('foo');
'notdirective';
~~~~~~~~~~~~~~~ [0]
})();

const a = () => {
'use strict'; "use cool"; "use lint"; var a = 1; "notdirective"; }
~~~~~~~~~~~~~~~ [0]

function fun2(a: number) {
return 0;
}
Expand All @@ -27,8 +46,6 @@ i = fun1() + fun1();
j = (j === 0 ? 5 : 6);
(j === 0 ? fun1() : fun2(j));
(a => 5)(4);
"use strict";

var obj = {};
delete obj.key;
function* g(): Iterable<number> {
Expand Down

0 comments on commit 3cd1b52

Please sign in to comment.