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
adidahiya committed Aug 21, 2015
2 parents 57efa6e + 551f9ca commit 7324496
Show file tree
Hide file tree
Showing 28 changed files with 527 additions and 235 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,21 @@ Installation

```npm install tslint```

##### `next` distribution

The [`next` branch of the TSLint repo](https://github.com/palantir/tslint/tree/next) tracks the latest TypeScript
compiler and allows you to lint TS code that uses the latest features of the language. Releases from this branch
are published to npm with the `next` dist-tag, so you can get the latest dev version of TSLint via
`npm install tslint@next`.

Usage
-----

Please first ensure that the TypeScript source files compile correctly.

##### CLI

usage: `tslint [options...] [file ...]`
usage: `tslint [options] [file ...]`

Options:

Expand All @@ -47,7 +54,7 @@ Please first ensure that the TypeScript source files compile correctly.

By default, configuration is loaded from `tslint.json`, if it exists in the current path, or the user's home directory, in that order.

tslint accepts the following commandline options:
tslint accepts the following command-line options:

-c, --config:
The location of the configuration file that tslint will use to
Expand Down Expand Up @@ -152,13 +159,15 @@ A sample configuration file with all options is available [here](https://github.
* `label-position` enforces labels only on sensible statements.
* `label-undefined` checks that labels are defined before usage.
* `max-line-length` sets the maximum length of a line.
* `member-access` enforces using explicit visibility on class members
* `member-ordering` enforces member ordering. Rule options:
* `public-before-private` All public members must be declared before private members
* `static-before-instance` All static members must be declared before instance members
* `variables-before-functions` All variables needs to be declared before functions
* `no-any` diallows usages of `any` as a type decoration.
* `no-arg` disallows access to `arguments.callee`.
* `no-bitwise` disallows bitwise operators.
* `no-conditional-assignment` disallows any type of assignment in any conditionals. This applies to `do-while`, `for`, `if`, and `while` statements.
* `no-console` disallows access to the specified functions on `console`. Rule options are functions to ban on the console variable.
* `no-consecutive-blank-lines` disallows having more than one blank line in a row in a file
* `no-construct` disallows access to the constructors of `String`, `Number`, and `Boolean`.
Expand Down
2 changes: 2 additions & 0 deletions docs/sample.tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"label-position": true,
"label-undefined": true,
"max-line-length": [true, 140],
"member-access": true,
"member-ordering": [true,
"public-before-private",
"static-before-instance",
Expand All @@ -27,6 +28,7 @@
"no-any": false,
"no-arg": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-console": [true,
"debug",
"info",
Expand Down
2 changes: 1 addition & 1 deletion lib/tslint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ declare module Lint {
protected visitVariableStatement(node: ts.VariableStatement): void;
protected visitWhileStatement(node: ts.WhileStatement): void;
protected visitNode(node: ts.Node): void;
private walkChildren(node);
protected walkChildren(node: ts.Node): void;
}
}
declare module Lint {
Expand Down
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"tslint": "./bin/tslint"
},
"main": "./lib/tslint",
"typescript": {
"definition": "lib/tslint.d.ts"
},
"repository": {
"type": "git",
"url": "https://github.com/palantir/tslint.git"
Expand All @@ -19,9 +22,9 @@
"test": "grunt"
},
"dependencies": {
"findup-sync": "~0.1.2",
"findup-sync": "~0.2.1",
"optimist": "~0.6.0",
"underscore.string": "~2.3.3"
"underscore.string": "~3.1.1"
},
"devDependencies": {
"chai": "^3.0.0",
Expand All @@ -33,9 +36,9 @@
"grunt-mocha-test": "^0.12.7",
"grunt-run": "^0.3.0",
"grunt-ts": "^4.1.0",
"grunt-tslint": "^2.3.1-beta",
"grunt-tslint": "latest",
"mocha": "^2.2.5",
"tslint": "^2.3.1-beta",
"tslint": "^2.4.2",
"typescript": "next"
},
"license": "Apache-2.0"
Expand Down
4 changes: 2 additions & 2 deletions src/formatterLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
module Lint {
const fs = require("fs");
const path = require("path");
const _s = require("underscore.string");
const {camelize} = require("underscore.string");

const moduleDirectory = path.dirname(module.filename);
const CORE_FORMATTERS_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "formatters");
Expand All @@ -27,7 +27,7 @@ module Lint {
return name;
}

const camelizedName = _s.camelize(name + "Formatter");
const camelizedName = camelize(name + "Formatter");

// first check for core formatters
let Formatter = loadFormatter(CORE_FORMATTERS_DIRECTORY, camelizedName);
Expand Down
2 changes: 1 addition & 1 deletion src/language/walker/syntaxWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ module Lint {
}
}

private walkChildren(node: ts.Node) {
protected walkChildren(node: ts.Node) {
ts.forEachChild(node, (child) => this.visitNode(child));
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/ruleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
module Lint {
const fs = require("fs");
const path = require("path");
const _s = require("underscore.string");
const {camelize, strLeft, strRight} = require("underscore.string");

const moduleDirectory = path.dirname(module.filename);
const CORE_RULES_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "rules");
Expand Down Expand Up @@ -68,8 +68,8 @@ module Lint {
// finally check for rules within the first level of directories,
// using dash prefixes as the sub-directory names
if (rulesDirectory) {
const subDirectory = _s.strLeft(rulesDirectory, "-");
const ruleName = _s.strRight(rulesDirectory, "-");
const subDirectory = strLeft(rulesDirectory, "-");
const ruleName = strRight(rulesDirectory, "-");
if (subDirectory !== rulesDirectory && ruleName !== rulesDirectory) {
camelizedName = transformName(ruleName);
Rule = loadRule(rulesDirectory, subDirectory, camelizedName);
Expand All @@ -89,7 +89,7 @@ module Lint {
if (nameMatch == null) {
return name + "Rule";
}
return nameMatch[1] + _s.camelize(nameMatch[2]) + nameMatch[3] + "Rule";
return nameMatch[1] + camelize(nameMatch[2]) + nameMatch[3] + "Rule";
}

function loadRule(...paths: string[]) {
Expand Down
26 changes: 13 additions & 13 deletions src/rules/forinRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ForInWalker extends Lint.RuleWalker {

// if this "if" statement has a single continue block
const ifStatement = (<ts.IfStatement> firstBlockStatement).thenStatement;
if (ForInWalker.nodeIsContinue(ifStatement)) {
if (nodeIsContinue(ifStatement)) {
return;
}
}
Expand All @@ -61,21 +61,21 @@ class ForInWalker extends Lint.RuleWalker {
const failure = this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING);
this.addFailure(failure);
}
}

private static nodeIsContinue(node: ts.Node) {
const kind = node.kind;
function nodeIsContinue(node: ts.Node) {
const kind = node.kind;

if (kind === ts.SyntaxKind.ContinueStatement) {
return true;
}
if (kind === ts.SyntaxKind.ContinueStatement) {
return true;
}

if (kind === ts.SyntaxKind.Block) {
const blockStatements = (<ts.Block> node).statements;
if (blockStatements.length === 1 && blockStatements[0].kind === ts.SyntaxKind.ContinueStatement) {
return true;
}
if (kind === ts.SyntaxKind.Block) {
const blockStatements = (<ts.Block> node).statements;
if (blockStatements.length === 1 && blockStatements[0].kind === ts.SyntaxKind.ContinueStatement) {
return true;
}

return false;
}

return false;
}
6 changes: 2 additions & 4 deletions src/rules/labelPositionRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING = "unexpected label on statement";

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

class LabelPosWalker extends Lint.RuleWalker {
private isValidLabel: boolean;

class LabelPositionWalker extends Lint.RuleWalker {
public visitLabeledStatement(node: ts.LabeledStatement) {
const statement = node.statement;
if (statement.kind !== ts.SyntaxKind.DoStatement
Expand Down
50 changes: 50 additions & 0 deletions src/rules/memberAccessRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2013 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.
*/

export class Rule extends Lint.Rules.AbstractRule {
static FAILURE_STRING = "default access modifier on member/method not allowed";

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

export class MemberAccessWalker extends Lint.RuleWalker {
constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) {
super(sourceFile, options);
}

public visitMethodDeclaration(node: ts.MethodDeclaration) {
this.validateVisibilityModifiers(node);
}

public visitPropertyDeclaration(node: ts.PropertyDeclaration) {
this.validateVisibilityModifiers(node);
}

private validateVisibilityModifiers(node: ts.Node) {
const hasAnyVisibilityModifiers = Lint.hasModifier(
node.modifiers,
ts.SyntaxKind.PublicKeyword,
ts.SyntaxKind.PrivateKeyword,
ts.SyntaxKind.ProtectedKeyword
);

if (!hasAnyVisibilityModifiers) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
}
}
54 changes: 25 additions & 29 deletions src/rules/memberOrderingRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,10 @@ interface IModifiers {
}

function getModifiers(isMethod: boolean, modifiers?: ts.ModifiersArray): IModifiers {
let modifierStrings: string[] = [];
if (modifiers != null) {
modifierStrings = modifiers.map((x) => {
return x.getText();
});
}

return {
isInstance: modifierStrings.indexOf("static") === -1,
isInstance: !Lint.hasModifier(modifiers, ts.SyntaxKind.StaticKeyword),
isMethod: isMethod,
isPrivate: modifierStrings.indexOf("private") !== -1
isPrivate: Lint.hasModifier(modifiers, ts.SyntaxKind.PrivateKeyword)
};
}

Expand All @@ -55,7 +48,7 @@ function toString(modifiers: IModifiers): string {
}

export class MemberOrderingWalker extends Lint.RuleWalker {
private previous: IModifiers;
private previousMember: IModifiers;

constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) {
super(sourceFile, options);
Expand All @@ -72,22 +65,22 @@ export class MemberOrderingWalker extends Lint.RuleWalker {
}

public visitMethodDeclaration(node: ts.MethodDeclaration) {
this.checkAndSetModifiers(node, getModifiers(true, node.modifiers));
this.checkModifiersAndSetPrevious(node, getModifiers(true, node.modifiers));
super.visitMethodDeclaration(node);
}

public visitMethodSignature(node: ts.SignatureDeclaration) {
this.checkAndSetModifiers(node, getModifiers(true, node.modifiers));
this.checkModifiersAndSetPrevious(node, getModifiers(true, node.modifiers));
super.visitMethodSignature(node);
}

public visitPropertyDeclaration(node: ts.PropertyDeclaration) {
this.checkAndSetModifiers(node, getModifiers(false, node.modifiers));
this.checkModifiersAndSetPrevious(node, getModifiers(false, node.modifiers));
super.visitPropertyDeclaration(node);
}

public visitPropertySignature(node: ts.Node) {
this.checkAndSetModifiers(node, getModifiers(false, node.modifiers));
this.checkModifiersAndSetPrevious(node, getModifiers(false, node.modifiers));
super.visitPropertySignature(node);
}

Expand All @@ -96,37 +89,40 @@ export class MemberOrderingWalker extends Lint.RuleWalker {
}

private resetPreviousModifiers() {
this.previous = {
this.previousMember = {
isInstance: false,
isMethod: false,
isPrivate: false
};
}

private checkAndSetModifiers(node: ts.Node, current: IModifiers) {
if (!this.canAppearAfter(this.previous, current)) {
const message = "Declaration of " + toString(current) +
" not allowed to appear after declaration of " + toString(this.previous);
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message));
private checkModifiersAndSetPrevious(node: ts.Node, currentMember: IModifiers) {
if (!this.canAppearAfter(this.previousMember, currentMember)) {
const failure = this.createFailure(
node.getStart(),
node.getWidth(),
`Declaration of ${toString(currentMember)} not allowed to appear after declaration of ${toString(this.previousMember)}`
);
this.addFailure(failure);
}
this.previous = current;
this.previousMember = currentMember;
}

private canAppearAfter(previous: IModifiers, current: IModifiers) {
if (previous == null || current == null) {
private canAppearAfter(previousMember: IModifiers, currentMember: IModifiers) {
if (previousMember == null || currentMember == null) {
return true;
}

if (this.hasOption(OPTION_VARIABLES_BEFORE_FUNCTIONS) && previous.isMethod !== current.isMethod) {
return Number(previous.isMethod) < Number(current.isMethod);
if (this.hasOption(OPTION_VARIABLES_BEFORE_FUNCTIONS) && previousMember.isMethod !== currentMember.isMethod) {
return Number(previousMember.isMethod) < Number(currentMember.isMethod);
}

if (this.hasOption(OPTION_STATIC_BEFORE_INSTANCE) && previous.isInstance !== current.isInstance) {
return Number(previous.isInstance) < Number(current.isInstance);
if (this.hasOption(OPTION_STATIC_BEFORE_INSTANCE) && previousMember.isInstance !== currentMember.isInstance) {
return Number(previousMember.isInstance) < Number(currentMember.isInstance);
}

if (this.hasOption(OPTION_PUBLIC_BEFORE_PRIVATE) && previous.isPrivate !== current.isPrivate) {
return Number(previous.isPrivate) < Number(current.isPrivate);
if (this.hasOption(OPTION_PUBLIC_BEFORE_PRIVATE) && previousMember.isPrivate !== currentMember.isPrivate) {
return Number(previousMember.isPrivate) < Number(currentMember.isPrivate);
}

return true;
Expand Down
Loading

0 comments on commit 7324496

Please sign in to comment.