Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Commit

Permalink
Upgrade TSLint to support TS 3.1 (#4274)
Browse files Browse the repository at this point in the history
* Upgrade TSLint so it supports TS 3.1

* Fix lint errors.

* Changes the node version from 4 to 6 for TS 2.1 tests.

Node 4 is no longer supported.

Unblocks #4274

* Revert tsutils upgrade.

* Revert unrelated yarn.lock changes
  • Loading branch information
bowenni authored and Josh Goldberg committed Dec 15, 2018
1 parent 198bb5a commit c7fc99b
Show file tree
Hide file tree
Showing 53 changed files with 238 additions and 159 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"tslint": "^5.8.0",
"tslint-config-prettier": "^1.13.0",
"tslint-test-config-non-relative": "file:test/external/tslint-test-config-non-relative",
"typescript": "~2.9.2"
"typescript": "~3.1.6"
},
"license": "Apache-2.0",
"engines": {
Expand Down
21 changes: 12 additions & 9 deletions src/language/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export function isBlockScopedVariable(
node: ts.VariableDeclaration | ts.VariableStatement,
): boolean {
if (node.kind === ts.SyntaxKind.VariableDeclaration) {
const parent = node.parent!;
const parent = node.parent;
return (
parent.kind === ts.SyntaxKind.CatchClause ||
isBlockScopedVariableDeclarationList(parent)
Expand All @@ -95,7 +95,7 @@ export function isBlockScopedBindingElement(node: ts.BindingElement): boolean {
export function getBindingElementVariableDeclaration(
node: ts.BindingElement,
): ts.VariableDeclaration | null {
let currentParent = node.parent! as ts.Node;
let currentParent = node.parent as ts.Node;
while (currentParent.kind !== ts.SyntaxKind.VariableDeclaration) {
if (currentParent.parent === undefined) {
return null; // function parameter, no variable declaration
Expand Down Expand Up @@ -177,7 +177,10 @@ export function isCombinedNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags):
*
* @deprecated no longer used
*/
export function isCombinedModifierFlagSet(node: ts.Node, flagToCheck: ts.ModifierFlags): boolean {
export function isCombinedModifierFlagSet(
node: ts.Declaration,
flagToCheck: ts.ModifierFlags,
): boolean {
// tslint:disable-next-line:no-bitwise
return (ts.getCombinedModifierFlags(node) & flagToCheck) !== 0;
}
Expand Down Expand Up @@ -378,7 +381,7 @@ export function forEachToken(
fullText,
token.kind,
{ tokenStart, fullStart: token.pos, end: token.end },
token.parent!,
token.parent,
);
}
}
Expand All @@ -396,7 +399,7 @@ function createTriviaHandler(sourceFile: ts.SourceFile, cb: ForEachTokenCallback
* This includes trailing trivia of the last token and the leading trivia of the current token
*/
function handleTrivia(start: number, end: number, token: ts.Node) {
const parent = token.parent!;
const parent = token.parent;
// prevent false positives by not scanning inside JsxText
if (!canHaveLeadingTrivia(token.kind, parent)) {
return;
Expand Down Expand Up @@ -471,7 +474,7 @@ function canHaveLeadingTrivia(tokenKind: ts.SyntaxKind, parent: ts.Node): boolea
// before a JsxExpression inside a JsxElement's body can only be other JsxChild, but no trivia
return (
parent.kind !== ts.SyntaxKind.JsxExpression ||
parent.parent!.kind !== ts.SyntaxKind.JsxElement
parent.parent.kind !== ts.SyntaxKind.JsxElement
);

case ts.SyntaxKind.LessThanToken:
Expand All @@ -481,7 +484,7 @@ function canHaveLeadingTrivia(tokenKind: ts.SyntaxKind, parent: ts.Node): boolea
case ts.SyntaxKind.JsxOpeningElement:
case ts.SyntaxKind.JsxSelfClosingElement:
// there can only be leading trivia if we are at the end of the top level element
return parent.parent!.parent!.kind !== ts.SyntaxKind.JsxElement;
return parent.parent.parent.kind !== ts.SyntaxKind.JsxElement;
default:
return true;
}
Expand All @@ -502,7 +505,7 @@ function canHaveTrailingTrivia(tokenKind: ts.SyntaxKind, parent: ts.Node): boole
// after a JsxExpression inside a JsxElement's body can only be other JsxChild, but no trivia
return (
parent.kind !== ts.SyntaxKind.JsxExpression ||
parent.parent!.kind !== ts.SyntaxKind.JsxElement
parent.parent.kind !== ts.SyntaxKind.JsxElement
);

case ts.SyntaxKind.GreaterThanToken:
Expand All @@ -512,7 +515,7 @@ function canHaveTrailingTrivia(tokenKind: ts.SyntaxKind, parent: ts.Node): boole
case ts.SyntaxKind.JsxClosingElement:
case ts.SyntaxKind.JsxSelfClosingElement:
// there can only be trailing trivia if we are at the end of the top level element
return parent.parent!.parent!.kind !== ts.SyntaxKind.JsxElement;
return parent.parent.parent.kind !== ts.SyntaxKind.JsxElement;

default:
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/arrayTypeRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function walk(ctx: Lint.WalkContext<Option>): void {
// Add a space if the type is preceded by 'as' and the node has no leading whitespace
const space =
parens === 0 &&
parent!.kind === ts.SyntaxKind.AsExpression &&
parent.kind === ts.SyntaxKind.AsExpression &&
node.getStart() === node.getFullStart();
const fix = [
new Lint.Replacement(elementType.getStart(), parens, `${space ? " " : ""}Array<`),
Expand Down
2 changes: 1 addition & 1 deletion src/rules/arrowReturnShorthandRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function createFix(
expr: ts.Expression,
text: string,
): Lint.Fix | undefined {
const statement = expr.parent!;
const statement = expr.parent;
const returnKeyword = utils.getChildOfKind(statement, ts.SyntaxKind.ReturnKeyword)!;
const arrow = utils.getChildOfKind(arrowFunction, ts.SyntaxKind.EqualsGreaterThanToken)!;
const openBrace = utils.getChildOfKind(body, ts.SyntaxKind.OpenBraceToken)!;
Expand Down
2 changes: 1 addition & 1 deletion src/rules/banCommaOperatorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function walk(ctx: Lint.WalkContext<void>) {
}

function isForLoopIncrementor(node: ts.Node) {
const parent = node.parent!;
const parent = node.parent;
return (
parent.kind === ts.SyntaxKind.ForStatement &&
(parent as ts.ForStatement).incrementor === node
Expand Down
2 changes: 1 addition & 1 deletion src/rules/callableTypesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function renderSuggestion(
const text = sourceFile.text.substring(start, call.end);

let suggestion = `${text.substr(0, colonPos)} =>${text.substr(colonPos + 1)}`;
if (shouldWrapSuggestion(parent.parent!)) {
if (shouldWrapSuggestion(parent.parent)) {
suggestion = `(${suggestion})`;
}
if (parent.kind === ts.SyntaxKind.InterfaceDeclaration) {
Expand Down
6 changes: 3 additions & 3 deletions src/rules/code-examples/functionConstructor.examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const codeExamples = [
`,
pass: Lint.Utils.dedent`
let doesNothing = () => {};
`
`,
},
{
config: Lint.Utils.dedent`
Expand All @@ -40,6 +40,6 @@ export const codeExamples = [
`,
pass: Lint.Utils.dedent`
let addNumbers = (a, b) => a + b;
`
}
`,
},
];
2 changes: 1 addition & 1 deletion src/rules/completed-docs/tagExclusion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class TagExclusion extends Exclusion<ITagExclusionDescriptor> {

private getDocumentationNode(node: ts.Node) {
if (node.kind === ts.SyntaxKind.VariableDeclaration) {
return node.parent!;
return node.parent;
}

return node;
Expand Down
6 changes: 3 additions & 3 deletions src/rules/completedDocsRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ function walk(context: Lint.WalkContext<ExclusionsMap>, typeChecker: ts.TypeChec
break;

case ts.SyntaxKind.MethodDeclaration:
if (node.parent!.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
if (node.parent.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
checkNode(node as ts.MethodDeclaration, ARGUMENT_METHODS);
}
break;
Expand All @@ -350,7 +350,7 @@ function walk(context: Lint.WalkContext<ExclusionsMap>, typeChecker: ts.TypeChec
case ts.SyntaxKind.VariableStatement:
// Only check variables at the namespace/module-level or file-level
// and not variables declared inside functions and other things.
switch (node.parent!.kind) {
switch (node.parent.kind) {
case ts.SyntaxKind.SourceFile:
case ts.SyntaxKind.ModuleBlock:
for (const declaration of (node as ts.VariableStatement).declarationList
Expand All @@ -362,7 +362,7 @@ function walk(context: Lint.WalkContext<ExclusionsMap>, typeChecker: ts.TypeChec

case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
if (node.parent!.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
if (node.parent.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
checkNode(node as ts.AccessorDeclaration, ARGUMENT_PROPERTIES);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rules/curlyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function walkAsNeeded(ctx: Lint.WalkContext<void>): void {
}

function isBlockUnnecessary(node: ts.Block): boolean {
const parent = node.parent!;
const parent = node.parent;
if (node.statements.length !== 1) {
return false;
}
Expand Down
6 changes: 5 additions & 1 deletion src/rules/cyclomaticComplexityRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
* limitations under the License.
*/

import { isFunctionScopeBoundary, isIdentifier } from "tsutils";
import { isIdentifier } from "tsutils";
import * as ts from "typescript";
import * as Lint from "../index";
import { isFunctionScopeBoundary } from "../utils";

export class Rule extends Lint.Rules.AbstractRule {
public static DEFAULT_THRESHOLD = 20;
Expand Down Expand Up @@ -90,7 +91,10 @@ function walk(ctx: Lint.WalkContext<{ threshold: number }>): void {
let complexity = 0;

return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
// tslint:disable:deprecation This is needed for https://github.com/palantir/tslint/pull/4274 and will be fixed once TSLint
// requires tsutils > 3.0.
if (isFunctionScopeBoundary(node)) {
// tslint:enable:deprecation
const old = complexity;
complexity = 1;
ts.forEachChild(node, cb);
Expand Down
16 changes: 8 additions & 8 deletions src/rules/deprecationRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function walk(ctx: Lint.WalkContext<void>, tc: ts.TypeChecker) {
}

function isDeclaration(identifier: ts.Identifier): boolean {
const parent = identifier.parent!;
const parent = identifier.parent;
switch (parent.kind) {
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.ClassExpression:
Expand Down Expand Up @@ -112,7 +112,7 @@ function isDeclaration(identifier: ts.Identifier): boolean {
case ts.SyntaxKind.PropertyAssignment:
return (
(parent as ts.PropertyAssignment).name === identifier &&
!isReassignmentTarget(identifier.parent!.parent as ts.ObjectLiteralExpression)
!isReassignmentTarget(identifier.parent.parent as ts.ObjectLiteralExpression)
);
case ts.SyntaxKind.BindingElement:
// return true for `b` in `const {a: b} = obj"`
Expand All @@ -126,10 +126,10 @@ function isDeclaration(identifier: ts.Identifier): boolean {
}

function getCallExpresion(node: ts.Expression): ts.CallLikeExpression | undefined {
let parent = node.parent!;
let parent = node.parent;
if (isPropertyAccessExpression(parent) && parent.name === node) {
node = parent;
parent = node.parent!;
parent = node.parent;
}
return isTaggedTemplateExpression(parent) ||
((isCallExpression(parent) || isNewExpression(parent)) && parent.expression === node)
Expand All @@ -146,9 +146,9 @@ function getDeprecation(node: ts.Identifier, tc: ts.TypeChecker): string | undef
}
}
let symbol: ts.Symbol | undefined;
const parent = node.parent!;
const parent = node.parent;
if (parent.kind === ts.SyntaxKind.BindingElement) {
symbol = tc.getTypeAtLocation(parent.parent!).getProperty(node.text);
symbol = tc.getTypeAtLocation(parent.parent).getProperty(node.text);
} else if (
(isPropertyAssignment(parent) && parent.name === node) ||
(isShorthandPropertyAssignment(parent) &&
Expand Down Expand Up @@ -215,10 +215,10 @@ function getDeprecationFromDeclarations(declarations?: ts.Declaration[]): string
declaration = getDeclarationOfBindingElement(declaration);
}
if (isVariableDeclaration(declaration)) {
declaration = declaration.parent!;
declaration = declaration.parent;
}
if (isVariableDeclarationList(declaration)) {
declaration = declaration.parent!;
declaration = declaration.parent;
}
const result = getDeprecationFromDeclaration(declaration);
if (result !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/functionConstructorRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class Rule extends Lint.Rules.AbstractRule {
`,
ruleName: "function-constructor",
type: "functionality",
typescriptOnly: false
typescriptOnly: false,
};

public static FAILURE = "Do not use the Function constructor to create functions.";
Expand Down
32 changes: 16 additions & 16 deletions src/rules/importBlacklistRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
ImportKind,
isExportDeclaration,
isImportDeclaration,
isNamedImports
isNamedImports,
} from "tsutils";
import * as ts from "typescript";
import * as Lint from "../index";
Expand All @@ -45,7 +45,7 @@ export class Rule extends Lint.Rules.AbstractRule {
oneOf: [
{
type: "string",
minLength: 1
minLength: 1,
},
{
type: "object",
Expand All @@ -54,20 +54,20 @@ export class Rule extends Lint.Rules.AbstractRule {
minItems: 1,
items: {
type: "string",
minLength: 1
}
}
}
]
}
minLength: 1,
},
},
},
],
},
},
optionExamples: [
true,
[true, "rxjs", "lodash"],
[true, "lodash", { lodash: ["pull", "pullAll"] }]
[true, "lodash", { lodash: ["pull", "pullAll"] }],
],
type: "functionality",
typescriptOnly: false
typescriptOnly: false,
};

public static WHOLE_MODULE_FAILURE_STRING =
Expand Down Expand Up @@ -120,7 +120,7 @@ function walk(ctx: Lint.WalkContext<Options>) {
}
return acc;
},
Object.create(null) as BannedImports
Object.create(null) as BannedImports,
);

for (const name of findImports(ctx.sourceFile, ImportKind.All)) {
Expand All @@ -137,7 +137,7 @@ function walk(ctx: Lint.WalkContext<Options>) {
ctx.addFailure(
name.getStart(ctx.sourceFile) + 1,
name.end - 1,
Rule.WHOLE_MODULE_FAILURE_STRING
Rule.WHOLE_MODULE_FAILURE_STRING,
);
continue;
}
Expand Down Expand Up @@ -210,17 +210,17 @@ function walk(ctx: Lint.WalkContext<Options>) {
...(importsDefaultExport ? ["default"] : []),
...(importsSpecificNamedExports
? (importClause!.namedBindings as ts.NamedImports).elements.map(
toExportName
toExportName,
)
: []),
...(exportClause !== undefined ? exportClause.elements.map(toExportName) : [])
...(exportClause !== undefined ? exportClause.elements.map(toExportName) : []),
];

for (const importName of namedImportsOrReExports) {
if (bansForModule.has(importName)) {
ctx.addFailureAtNode(
exportClause !== undefined ? exportClause : importClause!,
Rule.MAKE_NAMED_IMPORT_FAILURE_STRING(importName)
Rule.MAKE_NAMED_IMPORT_FAILURE_STRING(importName),
);
}
}
Expand All @@ -229,7 +229,7 @@ function walk(ctx: Lint.WalkContext<Options>) {
ctx.addFailure(
name.getStart(ctx.sourceFile) + 1,
name.end - 1,
Rule.IMPLICIT_NAMED_IMPORT_FAILURE_STRING
Rule.IMPLICIT_NAMED_IMPORT_FAILURE_STRING,
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rules/noAngleBracketTypeAssertionRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function walk(ctx: Lint.WalkContext<void>) {
}

function needsParens(node: ts.TypeAssertion): boolean {
const parent = node.parent!;
const parent = node.parent;
return (
isBinaryExpression(parent) &&
(parent.operatorToken.kind === ts.SyntaxKind.AmpersandToken ||
Expand Down
Loading

0 comments on commit c7fc99b

Please sign in to comment.