Skip to content

Commit

Permalink
Merge pull request palantir#106 from gscshoyru/hoisted-functions-unre…
Browse files Browse the repository at this point in the history
…achable

Fixes palantir#100 -- unreachable rule no longer triggers for function declarations
  • Loading branch information
ashwinr committed Mar 6, 2014
2 parents b1dd489 + 298929b commit a9f4d63
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Change Log
===

* [bug] hoisted functions no longer cause false positives for the `no-unreachable` rule
* [bug] the rule loader no longer transforms/ignores the leading and trailing underscores and dashes of rule names in the config file
* [feature] the `check-operator` option for the `whitespace` rule now checks whitespace around the => token
* [bug] `export import` statements no longer false positives for `no-unused-variable-rule`
Expand Down
17 changes: 12 additions & 5 deletions src/rules/noUnreachableRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,41 +33,48 @@ class UnreachableWalker extends Lint.RuleWalker {
}

public visitNode(node: TypeScript.SyntaxNode): void {
var previousReturned = this.hasReturned;
// function declarations can be hoisted -- so set hasReturned to false until we're done with the function
if (node.kind() === TypeScript.SyntaxKind.FunctionDeclaration) {
this.hasReturned = false;
}

if (this.hasReturned) {
this.hasReturned = false;
var position = this.position() + node.leadingTriviaWidth();
this.addFailure(this.createFailure(position, node.width(), Rule.FAILURE_STRING));
}

super.visitNode(node);

// if there is further code after the hoisted function and we returned before that code is unreachable
// so reset hasReturned to its previous state to check for that
if (node.kind() === TypeScript.SyntaxKind.FunctionDeclaration) {
this.hasReturned = previousReturned;
}
}

public visitBlock(node: TypeScript.BlockSyntax): void {
this.hasReturned = false;
super.visitBlock(node);
this.hasReturned = false;
}

public visitCaseSwitchClause(node: TypeScript.CaseSwitchClauseSyntax): void {
this.hasReturned = false;
super.visitCaseSwitchClause(node);
this.hasReturned = false;
}

public visitDefaultSwitchClause(node: TypeScript.DefaultSwitchClauseSyntax): void {
this.hasReturned = false;
super.visitDefaultSwitchClause(node);
this.hasReturned = false;
}

public visitIfStatement(node: TypeScript.IfStatementSyntax): void {
this.hasReturned = false;
super.visitIfStatement(node);
this.hasReturned = false;
}

public visitElseClause(node: TypeScript.ElseClauseSyntax): void {
this.hasReturned = false;
super.visitElseClause(node);
this.hasReturned = false;
}
Expand Down
21 changes: 21 additions & 0 deletions test/files/rules/nounreachable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,24 @@ function f5() {
var y = 7;
}

function f6() {
hoisted();
return 0;

function hoisted() {
return 0;
}
}

// more invalid code

function f7() {
hoisted();
return 0;

function hoisted() {
return 0;
}

var y = 7;
}
3 changes: 2 additions & 1 deletion test/rules/noUnreachableRuleTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ describe("<no-unreachable>", () => {
createFailure([6, 5], [6, 11]),
createFailure([13, 9], [13, 15]),
createFailure([25, 9], [25, 27]),
createFailure([28, 9], [28, 15])
createFailure([28, 9], [28, 15]),
createFailure([88, 5], [88, 15])
];
var actualFailures = Lint.Test.applyRuleOnFile(fileName, NoUnreachableRule);

Expand Down

0 comments on commit a9f4d63

Please sign in to comment.