Skip to content

Commit

Permalink
Use tsutils package for utilities (palantir#2217)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajafff authored and nchen63 committed Feb 24, 2017
1 parent dae82ca commit 7b8a24d
Show file tree
Hide file tree
Showing 16 changed files with 70 additions and 104 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"glob": "^7.1.1",
"optimist": "~0.6.0",
"resolve": "^1.1.7",
"tsutils": "^1.0.0",
"update-notifier": "^2.0.0"
},
"peerDependencies": {
Expand Down Expand Up @@ -70,7 +71,7 @@
"rimraf": "^2.5.4",
"tslint": "latest",
"tslint-test-config-non-relative": "file:test/external/tslint-test-config-non-relative",
"typescript": "2.1.4"
"typescript": "^2.1.6"
},
"license": "Apache-2.0",
"engines": {
Expand Down
28 changes: 14 additions & 14 deletions src/enableDisableRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import {AbstractRule} from "./language/rule/abstractRule";
import {forEachComment, TokenPosition} from "./language/utils";
import {IEnableDisablePosition} from "./ruleLoader";

export class EnableDisableRulesWalker {
Expand All @@ -42,11 +42,11 @@ export class EnableDisableRulesWalker {
}

public getEnableDisableRuleMap() {
forEachComment(this.sourceFile, (fullText, kind, pos) => {
const commentText = kind === ts.SyntaxKind.SingleLineCommentTrivia
? fullText.substring(pos.tokenStart + 2, pos.end)
: fullText.substring(pos.tokenStart + 2, pos.end - 2);
return this.handleComment(commentText, pos);
utils.forEachComment(this.sourceFile, (fullText, comment) => {
const commentText = comment.kind === ts.SyntaxKind.SingleLineCommentTrivia
? fullText.substring(comment.pos + 2, comment.end)
: fullText.substring(comment.pos + 2, comment.end - 2);
return this.handleComment(commentText, comment);
});

return this.enableDisableRuleMap;
Expand Down Expand Up @@ -85,7 +85,7 @@ export class EnableDisableRulesWalker {
}
}

private handleComment(commentText: string, pos: TokenPosition) {
private handleComment(commentText: string, range: ts.TextRange) {
// regex is: start of string followed by any amount of whitespace
// followed by tslint and colon
// followed by either "enable" or "disable"
Expand All @@ -110,32 +110,32 @@ export class EnableDisableRulesWalker {
rulesList = this.enabledRules;
}

this.handleTslintLineSwitch(rulesList, match[1] === "enable", match[2], pos);
this.handleTslintLineSwitch(rulesList, match[1] === "enable", match[2], range);
}
}

private handleTslintLineSwitch(rules: string[], isEnabled: boolean, modifier: string, pos: TokenPosition) {
private handleTslintLineSwitch(rules: string[], isEnabled: boolean, modifier: string, range: ts.TextRange) {
let start: number | undefined;
let end: number | undefined;

if (modifier === "line") {
// start at the beginning of the line where comment starts
start = this.getStartOfLinePosition(pos.tokenStart)!;
start = this.getStartOfLinePosition(range.pos)!;
// end at the beginning of the line following the comment
end = this.getStartOfLinePosition(pos.end, 1);
end = this.getStartOfLinePosition(range.end, 1);
} else if (modifier === "next-line") {
// start at the beginning of the line following the comment
start = this.getStartOfLinePosition(pos.end, 1);
start = this.getStartOfLinePosition(range.end, 1);
if (start === undefined) {
// no need to switch anything, there is no next line
return;
}
// end at the beginning of the line following the next line
end = this.getStartOfLinePosition(pos.end, 2);
end = this.getStartOfLinePosition(range.end, 2);
} else {
// switch rule for the rest of the file
// start at the current position, but skip end position
start = pos.tokenStart;
start = range.pos;
end = undefined;
}

Expand Down
26 changes: 4 additions & 22 deletions src/rules/adjacentOverloadSignaturesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -114,32 +115,13 @@ interface Overload {
name: string;
}

function isLiteralExpression(node: ts.Node): node is ts.LiteralExpression {
return node.kind === ts.SyntaxKind.StringLiteral || node.kind === ts.SyntaxKind.NumericLiteral;
}

export function getOverloadKey(node: ts.SignatureDeclaration): string | undefined {
const o = getOverload(node);
return o && o.key;
}

function getOverloadIfSignature(node: ts.TypeElement | ts.ClassElement): Overload | undefined {
return isSignatureDeclaration(node) ? getOverload(node) : undefined;
}

export function isSignatureDeclaration(node: ts.Node): node is ts.SignatureDeclaration {
switch (node.kind) {
case ts.SyntaxKind.ConstructSignature:
case ts.SyntaxKind.Constructor:
case ts.SyntaxKind.CallSignature:
case ts.SyntaxKind.CallSignature:
case ts.SyntaxKind.MethodSignature:
case ts.SyntaxKind.MethodDeclaration:
case ts.SyntaxKind.FunctionDeclaration:
return true;
default:
return false;
}
return utils.isSignatureDeclaration(node) ? getOverload(node) : undefined;
}

function getOverload(node: ts.SignatureDeclaration): Overload | undefined {
Expand Down Expand Up @@ -173,8 +155,8 @@ function getPropertyInfo(name: ts.PropertyName): { name: string, computed?: bool
return { name: (name as ts.Identifier).text };
case ts.SyntaxKind.ComputedPropertyName:
const { expression } = (name as ts.ComputedPropertyName);
return isLiteralExpression(expression) ? { name: expression.text } : { name: expression.getText(), computed: true };
return utils.isLiteralExpression(expression) ? { name: expression.text } : { name: expression.getText(), computed: true };
default:
return isLiteralExpression(name) ? { name: (name as ts.StringLiteral).text } : undefined;
return utils.isLiteralExpression(name) ? { name: (name as ts.StringLiteral).text } : undefined;
}
}
9 changes: 5 additions & 4 deletions src/rules/commentFormatRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -117,10 +118,10 @@ class CommentWalker extends Lint.RuleWalker {
}

public visitSourceFile(node: ts.SourceFile) {
Lint.forEachComment(node, (fullText, kind, pos) => {
if (kind === ts.SyntaxKind.SingleLineCommentTrivia) {
const commentText = fullText.substring(pos.tokenStart, pos.end);
const startPosition = pos.tokenStart + 2;
utils.forEachComment(node, (fullText, comment) => {
if (comment.kind === ts.SyntaxKind.SingleLineCommentTrivia) {
const commentText = fullText.substring(comment.pos, comment.end);
const startPosition = comment.pos + 2;
const width = commentText.length - 2;
if (this.hasOption(OPTION_SPACE)) {
if (!startsWithSpace(commentText)) {
Expand Down
14 changes: 3 additions & 11 deletions src/rules/importBlacklistRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";
import * as Lint from "../index";

Expand Down Expand Up @@ -66,7 +67,7 @@ class ImportBlacklistWalker extends Lint.RuleWalker {
}

public visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) {
if (isExternalModuleReference(node.moduleReference) &&
if (utils.isExternalModuleReference(node.moduleReference) &&
node.moduleReference.expression !== undefined) {
// If it's an import require and not an import alias
this.checkForBannedImport(node.moduleReference.expression);
Expand All @@ -80,7 +81,7 @@ class ImportBlacklistWalker extends Lint.RuleWalker {
}

private checkForBannedImport(expression: ts.Expression) {
if (isStringLiteral(expression) && this.hasOption(expression.text)) {
if (utils.isTextualLiteral(expression) && this.hasOption(expression.text)) {
this.addFailureFromStartToEnd(
expression.getStart(this.getSourceFile()) + 1,
expression.getEnd() - 1,
Expand All @@ -89,12 +90,3 @@ class ImportBlacklistWalker extends Lint.RuleWalker {
}
}
}

function isStringLiteral(node: ts.Node): node is ts.LiteralExpression {
return node.kind === ts.SyntaxKind.StringLiteral ||
node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral;
}

function isExternalModuleReference(node: ts.ModuleReference): node is ts.ExternalModuleReference {
return node.kind === ts.SyntaxKind.ExternalModuleReference;
}
7 changes: 4 additions & 3 deletions src/rules/jsdocFormatRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -50,9 +51,9 @@ export class Rule extends Lint.Rules.AbstractRule {

class JsdocWalker extends Lint.RuleWalker {
public visitSourceFile(node: ts.SourceFile) {
Lint.forEachComment(node, (fullText, kind, pos) => {
if (kind === ts.SyntaxKind.MultiLineCommentTrivia) {
this.findFailuresForJsdocComment(fullText.substring(pos.tokenStart, pos.end), pos.tokenStart);
utils.forEachComment(node, (fullText, comment) => {
if (comment.kind === ts.SyntaxKind.MultiLineCommentTrivia) {
this.findFailuresForJsdocComment(fullText.substring(comment.pos, comment.end), comment.pos);
}
});
}
Expand Down
7 changes: 2 additions & 5 deletions src/rules/newlineBeforeReturnRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";
import * as Lint from "../index";

Expand Down Expand Up @@ -47,7 +48,7 @@ class NewlineBeforeReturnWalker extends Lint.RuleWalker {
super.visitReturnStatement(node);

const parent = node.parent!;
if (!isBlockLike(parent)) {
if (!utils.isBlockLike(parent)) {
// `node` is the only statement within this "block scope". No need to do any further validation.
return;
}
Expand Down Expand Up @@ -75,7 +76,3 @@ class NewlineBeforeReturnWalker extends Lint.RuleWalker {
}
}
}

function isBlockLike(node: ts.Node): node is ts.BlockLike {
return "statements" in node;
}
19 changes: 10 additions & 9 deletions src/rules/noTrailingWhitespaceRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -73,29 +74,29 @@ export class Rule extends Lint.Rules.AbstractRule {
function walk(ctx: Lint.WalkContext<IgnoreOption>) {
let lastSeenWasWhitespace = false;
let lastSeenWhitespacePosition = 0;
Lint.forEachToken(ctx.sourceFile, false, (fullText, kind, pos) => {
utils.forEachTokenWithTrivia(ctx.sourceFile, (fullText, kind, range) => {
if (kind === ts.SyntaxKind.NewLineTrivia || kind === ts.SyntaxKind.EndOfFileToken) {
if (lastSeenWasWhitespace) {
reportFailure(ctx, lastSeenWhitespacePosition, pos.tokenStart);
reportFailure(ctx, lastSeenWhitespacePosition, range.pos);
}
lastSeenWasWhitespace = false;
} else if (kind === ts.SyntaxKind.WhitespaceTrivia) {
lastSeenWasWhitespace = true;
lastSeenWhitespacePosition = pos.tokenStart;
lastSeenWhitespacePosition = range.pos;
} else {
if (ctx.options !== IgnoreOption.Comments) {
if (kind === ts.SyntaxKind.SingleLineCommentTrivia) {
const commentText = fullText.substring(pos.tokenStart + 2, pos.end);
const commentText = fullText.substring(range.pos + 2, range.end);
const match = /\s+$/.exec(commentText);
if (match !== null) {
reportFailure(ctx, pos.end - match[0].length, pos.end);
reportFailure(ctx, range.end - match[0].length, range.end);
}
} else if (kind === ts.SyntaxKind.MultiLineCommentTrivia &&
(ctx.options !== IgnoreOption.JsDoc ||
fullText[pos.tokenStart + 2] !== "*" ||
fullText[pos.tokenStart + 3] === "*")) {
let startPos = pos.tokenStart + 2;
const commentText = fullText.substring(startPos, pos.end - 2);
fullText[range.pos + 2] !== "*" ||
fullText[range.pos + 3] === "*")) {
let startPos = range.pos + 2;
const commentText = fullText.substring(startPos, range.end - 2);
const lines = commentText.split("\n");
// we don't want to check the content of the last comment line, as it is always followed by */
const len = lines.length - 1;
Expand Down
7 changes: 2 additions & 5 deletions src/rules/noUnnecessaryInitializerRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -45,7 +46,7 @@ export class Rule extends Lint.Rules.AbstractRule {

class Walker extends Lint.RuleWalker {
public visitVariableDeclaration(node: ts.VariableDeclaration) {
if (isBindingPattern(node.name)) {
if (utils.isBindingPattern(node.name)) {
for (const elem of node.name.elements) {
if (elem.kind === ts.SyntaxKind.BindingElement) {
this.checkInitializer(elem);
Expand Down Expand Up @@ -115,7 +116,3 @@ function isUndefined(node: ts.Node | undefined): boolean {
node.kind === ts.SyntaxKind.Identifier &&
(node as ts.Identifier).originalKeywordKind === ts.SyntaxKind.UndefinedKeyword;
}

function isBindingPattern(node: ts.Node): node is ts.ArrayBindingPattern | ts.ObjectBindingPattern {
return node.kind === ts.SyntaxKind.ArrayBindingPattern || node.kind === ts.SyntaxKind.ObjectBindingPattern;
}
8 changes: 2 additions & 6 deletions src/rules/noUnnecessaryQualifierRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import * as utils from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand Down Expand Up @@ -67,7 +68,7 @@ class Walker extends Lint.ProgramAwareRuleWalker {
break;
case ts.SyntaxKind.PropertyAccessExpression:
const { expression, name } = node as ts.PropertyAccessExpression;
if (isEntityNameExpression(expression)) {
if (utils.isEntityNameExpression(expression)) {
this.visitNamespaceAccess(node, expression, name);
break;
}
Expand Down Expand Up @@ -126,11 +127,6 @@ class Walker extends Lint.ProgramAwareRuleWalker {
}
}

function isEntityNameExpression(expr: ts.Expression): expr is ts.EntityNameExpression {
return expr.kind === ts.SyntaxKind.Identifier ||
expr.kind === ts.SyntaxKind.PropertyAccessExpression && isEntityNameExpression((expr as ts.PropertyAccessExpression).expression);
}

// TODO: Should just be `===`. See https://github.com/palantir/tslint/issues/1969
function nodesAreEqual(a: ts.Node, b: ts.Node) {
return a.pos === b.pos;
Expand Down
10 changes: 4 additions & 6 deletions src/rules/noUnsafeAnyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ export class Rule extends Lint.Rules.TypedRule {
}
}

// This is marked @internal, but we need it!
const isExpression: (node: ts.Node) => node is ts.Expression = (ts as any).isExpression;

class Walker extends Lint.ProgramAwareRuleWalker {
public visitNode(node: ts.Node) {
if (ts.isExpression(node) && isAny(this.getType(node)) && !this.isAllowedLocation(node)) {
if (isExpression(node) && isAny(this.getType(node)) && !this.isAllowedLocation(node)) {
this.addFailureAtNode(node, Rule.FAILURE_STRING);
} else {
super.visitNode(node);
Expand Down Expand Up @@ -111,8 +114,3 @@ class Walker extends Lint.ProgramAwareRuleWalker {
function isAny(type: ts.Type | undefined): boolean {
return type !== undefined && Lint.isTypeFlagSet(type, ts.TypeFlags.Any);
}

// This is marked @internal, but we need it!
declare module "typescript" {
export function isExpression(node: ts.Node): node is ts.Expression;
}
Loading

0 comments on commit 7b8a24d

Please sign in to comment.