Skip to content

Commit

Permalink
Migrate use strict rule to 1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
adidahiya committed Jan 22, 2015
1 parent eba4e7a commit 1ce75e7
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 37 deletions.
4 changes: 3 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ module.exports = function(grunt) {
'src/rules/radixRule.ts',
'src/rules/semicolonRule.ts',
'src/rules/tripleEqualsRule.ts',
'src/rules/variableNameRule.ts'
'src/rules/variableNameRule.ts',
'src/rules/useStrictRule.ts'
],
outDir: 'build/rules/'
},
Expand Down Expand Up @@ -144,6 +145,7 @@ module.exports = function(grunt) {
'test/rules/semicolonRuleTests.ts',
'test/rules/tripleEqualsRuleTests.ts',
'test/rules/variableNameRuleTests.ts',
'test/rules/useStrictRuleTests.ts',

'!test/files/**/*.ts'
],
Expand Down
2 changes: 2 additions & 0 deletions lib/tslint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ declare module Lint {
visitExpressionStatement(node: ts.ExpressionStatement): void;
visitForStatement(node: ts.ForStatement): void;
visitForInStatement(node: ts.ForInStatement): void;
visitFunctionDeclaration(node: ts.FunctionDeclaration): void;
visitIfStatement(node: ts.IfStatement): void;
visitImportDeclaration(node: ts.ImportDeclaration): void;
visitInterfaceDeclaration(node: ts.InterfaceDeclaration): void;
Expand All @@ -69,6 +70,7 @@ declare module Lint {
visitNewExpression(node: ts.NewExpression): void;
visitObjectLiteralExpression(node: ts.ObjectLiteralExpression): void;
visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression): void;
visitModuleDeclaration(node: ts.ModuleDeclaration): void;
visitPropertyAccessExpression(node: ts.PropertyAccessExpression): void;
visitPropertyAssignment(node: ts.PropertyAssignment): void;
visitPropertyDeclaration(node: ts.PropertyDeclaration): void;
Expand Down
16 changes: 16 additions & 0 deletions src/language/walker/syntaxWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ module Lint {
this.walkChildren(node);
}

public visitFunctionDeclaration(node: ts.FunctionDeclaration) {
this.walkChildren(node);
}

public visitIfStatement(node: ts.IfStatement) {
this.walkChildren(node);
}
Expand Down Expand Up @@ -99,6 +103,10 @@ module Lint {
this.walkChildren(node);
}

public visitModuleDeclaration(node: ts.ModuleDeclaration) {
this.walkChildren(node);
}

public visitPropertyAccessExpression(node: ts.PropertyAccessExpression) {
this.walkChildren(node);
}
Expand Down Expand Up @@ -189,6 +197,10 @@ module Lint {
this.visitForInStatement(<ts.ForInStatement> node);
break;

case ts.SyntaxKind.FunctionDeclaration:
this.visitFunctionDeclaration(<ts.FunctionDeclaration> node);
break;

case ts.SyntaxKind.IfStatement:
this.visitIfStatement(<ts.IfStatement> node);
break;
Expand All @@ -209,6 +221,10 @@ module Lint {
this.visitMethodDeclaration(<ts.MethodDeclaration> node);
break;

case ts.SyntaxKind.ModuleDeclaration:
this.visitModuleDeclaration(<ts.ModuleDeclaration> node);
break;

case ts.SyntaxKind.NewExpression:
this.visitNewExpression(<ts.NewExpression> node);
break;
Expand Down
61 changes: 26 additions & 35 deletions src/rules/useStrictRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
* limitations under the License.
*/

/// <reference path='../../lib/tslint.d.ts' />
///<reference path='../../lib/tslint.d.ts' />

export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING = "missing 'use strict'";

public apply(syntaxTree: TypeScript.SyntaxTree): Lint.RuleFailure[] {
return this.applyWithWalker(new UseStrictWalker(syntaxTree, this.getOptions()));
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
var useStrictWalker = new UseStrictWalker(sourceFile, this.getOptions());
return this.applyWithWalker(useStrictWalker);
}
}

Expand All @@ -34,61 +35,51 @@ class UseStrictWalker extends Lint.ScopeAwareRuleWalker<{}> {
return {};
}

public visitModuleDeclaration(node: TypeScript.ModuleDeclarationSyntax): void {
var childCount = TypeScript.childCount(node.modifiers);
public visitModuleDeclaration(node: ts.ModuleDeclaration) {
var modifiers = node.modifiers;
var hasDeclareModifier = (modifiers != null) && (modifiers.length > 0) && (modifiers[0].kind === ts.SyntaxKind.DeclareKeyword);

// current depth is 2: global scope and the scope created by this module
// but skip declare module statements
if (this.getCurrentDepth() === 2 &&
!(childCount > 0 && TypeScript.childAt(node.modifiers, 0).kind() === TypeScript.SyntaxKind.DeclareKeyword)) {

if (this.hasOption(UseStrictWalker.OPTION_CHECK_MODULE)) {
this.checkUseStrict(node, node.moduleElements);
if (this.getCurrentDepth() === 2 && !hasDeclareModifier) {
if (node.body != null && this.hasOption(UseStrictWalker.OPTION_CHECK_MODULE)) {
this.handleBlock(node, <ts.Block> node.body);
}
}

super.visitModuleDeclaration(node);
}

public visitFunctionDeclaration(node: TypeScript.FunctionDeclarationSyntax): void {
public visitFunctionDeclaration(node: ts.FunctionDeclaration) {
// current depth is 2: global scope and the scope created by this function
if (this.getCurrentDepth() === 2) {
if (node.block && this.hasOption(UseStrictWalker.OPTION_CHECK_FUNCTION)) {
this.checkUseStrict(node, node.block.statements);
}
if (this.getCurrentDepth() === 2 &&
node.body != null &&
this.hasOption(UseStrictWalker.OPTION_CHECK_FUNCTION)) {
this.handleBlock(node, node.body);
}

super.visitFunctionDeclaration(node);
}

private checkUseStrict(node: TypeScript.ISyntaxNode, syntaxList: TypeScript.ISyntaxElement[]) {
private handleBlock(node: ts.Declaration, block: ts.Block) {
var isFailure = true;

if (syntaxList.length > 0) {
var firstStatement = syntaxList[0];
if (block.statements != null && block.statements.length > 0) {
var firstStatement = block.statements[0];

if (firstStatement.kind() === TypeScript.SyntaxKind.ExpressionStatement && TypeScript.childCount(firstStatement) === 2) {
var firstChild = TypeScript.childAt(firstStatement, 0);
var secondChild = TypeScript.childAt(firstStatement, 1);
if (firstStatement.kind === ts.SyntaxKind.ExpressionStatement && firstStatement.getChildCount() === 2) {
var firstChild = firstStatement.getChildAt(0);
var secondChild = firstStatement.getChildAt(1);

if (TypeScript.isToken(firstChild)) {
var firstToken = TypeScript.firstToken(firstChild);
if (TypeScript.tokenValueText(firstToken) === UseStrictWalker.USE_STRICT_STRING) {
if (secondChild.kind() === TypeScript.SyntaxKind.SemicolonToken) {
isFailure = false;
}
}
if (firstChild.kind === ts.SyntaxKind.StringLiteral &&
(<ts.StringLiteralExpression> firstChild).text === UseStrictWalker.USE_STRICT_STRING &&
secondChild.kind === ts.SyntaxKind.SemicolonToken) {
isFailure = false;
}
}
}

if (isFailure) {
this.addUseStrictFailure(node);
this.addFailure(this.createFailure(node.getStart(), node.getFirstToken().getWidth(), Rule.FAILURE_STRING));
}
}

private addUseStrictFailure(node: TypeScript.ISyntaxNode) {
var position = this.getPosition() + TypeScript.leadingTriviaWidth(node);
this.addFailure(this.createFailure(position, TypeScript.width(TypeScript.firstToken(node)), Rule.FAILURE_STRING));
}
}
1 change: 0 additions & 1 deletion test/rules/useStrictRuleTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ describe("<use-strict>", () => {

it("enforces checks for 'use strict' in functions", () => {
var expectedFailures = Lint.Test.createFailure(fileName, [14, 1], [14, 9], UseStrictRule.FAILURE_STRING);

Lint.Test.assertContainsFailure(actualFailures, expectedFailures);
});

Expand Down

0 comments on commit 1ce75e7

Please sign in to comment.