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

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: palantir/tslint
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5.19.0
Choose a base ref
...
head repository: palantir/tslint
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5.20.0
Choose a head ref
  • 13 commits
  • 42 files changed
  • 9 contributors

Commits on Aug 21, 2019

  1. Copy the full SHA
    b645f2c View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    00e5d2d View commit details

Commits on Aug 25, 2019

  1. 4746: fix weird failures in strict-boolean-expressions for 'ignore-rh…

    …s' option (#4833)
    
    * 4746: fix weird failures in strict-boolean-expressions for 'ignore-rhs' option
    
    * fix test2.1
    tanmoyopenroot authored and Josh Goldberg committed Aug 25, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    85d4125 View commit details

Commits on Aug 29, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6d79381 View commit details

Commits on Aug 30, 2019

  1. Copy the full SHA
    abd83b5 View commit details

Commits on Aug 31, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    89d731f View commit details
  2. Fix bug where the strict ts flag wasn't recognised correctly by `no-u…

    …nnecessary-type-assertion` (#4841)
    
    * Fix bug where the strict ts flag wasn't recognised correctly
    
    This commit fixes #4840
    
    * Make sure to only test 'strict' flag option for tsc 2.4+
    
    * Review: put getCompilerOptions into var
    guidsdo authored and Josh Goldberg committed Aug 31, 2019
    Copy the full SHA
    44947c5 View commit details

Commits on Sep 5, 2019

  1. Copy the full SHA
    0f2a540 View commit details

Commits on Sep 9, 2019

  1. Added allow-generics option to invalid-void rule (#4839)

    Josh Goldberg authored and adidahiya committed Sep 9, 2019
    Copy the full SHA
    a15541d View commit details
  2. Copy the full SHA
    38ef9d9 View commit details
  3. Copy the full SHA
    7659cd9 View commit details

Commits on Sep 10, 2019

  1. Copy the full SHA
    b6c8b0c View commit details
  2. Copy the full SHA
    98edf1a View commit details
Showing with 1,496 additions and 180 deletions.
  1. +2 −0 .github/ISSUE_TEMPLATE/rule-suggestion.md
  2. +25 −2 CHANGELOG.md
  3. +2 −2 package.json
  4. +1 −1 src/linter.ts
  5. +2 −0 src/rules/arrayTypeRule.ts
  6. +8 −2 src/rules/fileNameCasingRule.ts
  7. +107 −8 src/rules/invalidVoidRule.ts
  8. +6 −1 src/rules/noUnnecessaryTypeAssertionRule.ts
  9. +123 −50 src/rules/objectLiteralShorthandRule.ts
  10. +1 −1 src/rules/strictBooleanExpressionsRule.ts
  11. +86 −9 src/rules/unnecessaryConstructorRule.ts
  12. +4 −0 test/rules/array-type/array-simple/test.ts.fix
  13. +6 −0 test/rules/array-type/array-simple/test.ts.lint
  14. +3 −3 test/rules/file-name-casing/complex/tslint.json
  15. +2 −2 test/rules/file-name-casing/ignore/tslint.json
  16. +16 −0 test/rules/invalid-void/allow-generics/false/test.ts.lint
  17. +7 −0 test/rules/invalid-void/allow-generics/false/tslint.json
  18. +11 −0 test/rules/invalid-void/allow-generics/true/test.ts.lint
  19. +7 −0 test/rules/invalid-void/allow-generics/true/tslint.json
  20. +12 −0 test/rules/invalid-void/allow-generics/whitelist/test.ts.lint
  21. +7 −0 test/rules/invalid-void/allow-generics/whitelist/tslint.json
  22. +10 −4 test/rules/invalid-void/{ → default}/test.ts.lint
  23. 0 test/rules/invalid-void/{ → default}/tslint.json
  24. +104 −0 test/rules/no-unnecessary-type-assertion/strict/test.ts.fix
  25. +125 −0 test/rules/no-unnecessary-type-assertion/strict/test.ts.lint
  26. +6 −0 test/rules/no-unnecessary-type-assertion/strict/tsconfig.json
  27. +5 −0 test/rules/no-unnecessary-type-assertion/strict/tslint.json
  28. +10 −8 test/rules/object-literal-shorthand/always/test.ts.lint
  29. +13 −13 test/rules/object-literal-shorthand/never/test.ts.lint
  30. +45 −0 test/rules/object-literal-shorthand/onlyMethods/test.ts.fix
  31. +58 −0 test/rules/object-literal-shorthand/onlyMethods/test.ts.lint
  32. +11 −0 test/rules/object-literal-shorthand/onlyMethods/tslint.json
  33. +43 −0 test/rules/strict-boolean-expressions/default/test.ts.lint
  34. +31 −5 test/rules/strict-boolean-expressions/ignore-rhs/test.ts.lint
  35. +147 −0 test/rules/unnecessary-constructor/check-super-calls/test.ts.fix
  36. +188 −0 test/rules/unnecessary-constructor/check-super-calls/test.ts.lint
  37. +8 −0 test/rules/unnecessary-constructor/check-super-calls/tslint.json
  38. +159 −0 test/rules/unnecessary-constructor/default/test.ts.fix
  39. +90 −0 test/rules/unnecessary-constructor/{ → default}/test.ts.lint
  40. 0 test/rules/unnecessary-constructor/{ → default}/tslint.json
  41. +0 −69 test/rules/unnecessary-constructor/test.ts.fix
  42. +5 −0 yarn.lock
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/rule-suggestion.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ about: Suggest a new rule for TSLint

### Rule Suggestion

_Note: TSLint has stopped accepting new core rules because it is being deprecated in favor of ESLint. Your request is likely to be rejected with the suggestion to maintain a custom rule outside this repository. See [the roadmap](https://github.com/palantir/tslint/issues/4534) for more details._

**Is your rule for a general problem or is it specific to your development style?**

**What does your suggested rule do?**
27 changes: 25 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# Change Log

## v5.20.0

- [bugfix] fix [`strict-boolean-expressions`](https://palantir.github.io/tslint/rules/strict-boolean-expressions/) false positive with `"ignore-rhs"` option (#4833)
- [bugfix] fix [`no-unnecessary-type-assertion`](https://palantir.github.io/tslint/rules/no-unnecessary-type-assertion/) no error when `"strict": true` in compiler flags (#4841)
- [bugfix] "ignore" option for [`file-name-casing`](https://palantir.github.io/tslint/rules/file-name-casing/) rule works correctly (#4848)
- [bugfix] fix [`array-type`](https://palantir.github.io/tslint/rules/array-type/) false positive for simple parenthesized types with "array-simple" option (#4844)
- [new-rule-option] [`object-literal-shorthand`](https://palantir.github.io/tslint/rules/object-literal-shorthand/) supports `{"property"?: "never", "method"?: "never"}` as config options (#4842)
- [new-rule-option]: `allow-generics` option for [`invalid-void`](https://palantir.github.io/tslint/rules/invalid-void) rule (#4839)
- [new-rule-option] `check-super-calls` option for [`unnecessary-constructor`](https://palantir.github.io/tslint/rules/unnecessary-constructor/) rule (#4813)
- [chore] Upgrade `diff` dependency to v4.0.1 (#4845, #4852)

Thanks to our contributors!

- Bas Bosman
- Tanmoy Bhowmik
- David Zulaica
- Maxime Kjaer
- @guidsdo
- Pavel Birukov
- Josh Goldberg
- Akshaya Srivatsa


## v5.19.0

- [bugfix] relax [`promise-function-async`](https://palantir.github.io/tslint/rules/promise-function-async/) for short parenthesized arrow functions (#4765)
@@ -12,9 +35,9 @@
- [new-rule-option] `variable-declaration-ignore-function` option for [`typedef`](https://palantir.github.io/tslint/rules/typedef/) rule (#4769)
- [new-rule-option] `ignore-blank-lines` option for [`object-literal-sort-keys`](https://palantir.github.io/tslint/rules/object-literal-sort-keys/) rule (#4808)
- [new-rule] [`no-for-in`](https://palantir.github.io/tslint/rules/no-for-in/) (#4747)
- [new-rule] [`no-invalid-void`](https://palantir.github.io/tslint/rules/no-invalid-void/) (#4736)
- [new-rule] [`invalid-void`](https://palantir.github.io/tslint/rules/invalid-void/) (#4736)
- [new-rule] [`strict-string-expressions`](https://palantir.github.io/tslint/rules/strict-string-expressions/) reports errors on type coercions found in string expressions (#4807)
- [new-rule] ['no-promise-as-boolean'](https://palantir.github.io/tslint/rules/no-promise-as-boolean/) (#4790)
- [new-rule] [`no-promise-as-boolean`](https://palantir.github.io/tslint/rules/no-promise-as-boolean/) (#4790)
- [docs] link to OSS fellowship medium post in README (#4821)

Thanks to our contributors!
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tslint",
"version": "5.19.0",
"version": "5.20.0",
"description": "An extensible static analysis linter for the TypeScript language",
"bin": {
"tslint": "./bin/tslint"
@@ -33,7 +33,7 @@
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^3.2.0",
"diff": "^4.0.1",
"glob": "^7.1.1",
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
2 changes: 1 addition & 1 deletion src/linter.ts
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ import { arrayify, dedent, flatMap, mapDefined } from "./utils";
* Linter that can lint multiple files in consecutive runs.
*/
export class Linter {
public static VERSION = "5.19.0";
public static VERSION = "5.20.0";

public static findConfiguration = findConfiguration;
public static findConfigurationPath = findConfigurationPath;
2 changes: 2 additions & 0 deletions src/rules/arrayTypeRule.ts
Original file line number Diff line number Diff line change
@@ -164,6 +164,8 @@ function isSimpleType(nodeType: ts.TypeNode): boolean {
case ts.SyntaxKind.ThisType:
case ts.SyntaxKind.UnknownKeyword:
return true;
case ts.SyntaxKind.ParenthesizedType:
return isSimpleType((nodeType as ts.ParenthesizedTypeNode).type);
case ts.SyntaxKind.TypeReference:
// TypeReferences must be non-generic or be another Array with a simple type
const { typeName, typeArguments } = nodeType as ts.TypeReferenceNode;
10 changes: 8 additions & 2 deletions src/rules/fileNameCasingRule.ts
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ import { isCamelCased, isKebabCased, isPascalCased, isSnakeCased } from "../util
enum Casing {
CamelCase = "camel-case",
PascalCase = "pascal-case",
Ignored = "ignored",
Ignored = "ignore",
KebabCase = "kebab-case",
SnakeCase = "snake-case",
}
@@ -40,7 +40,13 @@ type ValidationResult = Casing | undefined;

type Validator<T extends Config> = (sourceFile: ts.SourceFile, casing: T) => ValidationResult;

const rules = [Casing.CamelCase, Casing.PascalCase, Casing.KebabCase, Casing.SnakeCase];
const rules = [
Casing.CamelCase,
Casing.Ignored,
Casing.PascalCase,
Casing.KebabCase,
Casing.SnakeCase,
];

const validCasingOptions = new Set(rules);

115 changes: 107 additions & 8 deletions src/rules/invalidVoidRule.ts
Original file line number Diff line number Diff line change
@@ -15,35 +15,84 @@
* limitations under the License.
*/

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

import * as Lint from "../index";

const OPTION_ALLOW_GENERICS = "allow-generics";

interface Options {
allowGenerics: boolean | Set<string>;
}

type RawOptions =
| undefined
| {
[OPTION_ALLOW_GENERICS]?: boolean | Set<string>;
};

type GenericReference = ts.NewExpression | ts.TypeReferenceNode;

export class Rule extends Lint.Rules.AbstractRule {
/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
ruleName: "invalid-void",
description: Lint.Utils.dedent`
Disallows usage of \`void\` type outside of return type.
Disallows usage of \`void\` type outside of generic or return types.
If \`void\` is used as return type, it shouldn't be a part of intersection/union type.`,
rationale: Lint.Utils.dedent`
The \`void\` type means "nothing" or that a function does not return any value,
in contra with implicit \`undefined\` type which means that a function returns a value \`undefined\`.
So "nothing" cannot be mixed with any other types.
If you need this - use \`undefined\` type instead.`,
hasFix: false,
optionsDescription: "Not configurable.",
options: null,
optionExamples: [true],
optionsDescription: Lint.Utils.dedent`
If \`${OPTION_ALLOW_GENERICS}\` is specified as \`false\`, then generic types will no longer be allowed to to be \`void\`.
Alternately, provide an array of strings for \`${OPTION_ALLOW_GENERICS}\` to exclusively allow generic types by those names.`,
options: {
type: "object",
properties: {
[OPTION_ALLOW_GENERICS]: {
oneOf: [
{ type: "boolean" },
{ type: "array", items: { type: "string" }, minLength: 1 },
],
},
},
additionalProperties: false,
},
optionExamples: [
true,
[true, { [OPTION_ALLOW_GENERICS]: false }],
[true, { [OPTION_ALLOW_GENERICS]: ["Promise", "PromiseLike"] }],
],
type: "maintainability",
typescriptOnly: true,
};
/* tslint:enable:object-literal-sort-keys */

public static FAILURE_STRING = "void is not a valid type other than return types";
public static FAILURE_STRING_ALLOW_GENERICS =
"void is only valid as a return type or generic type variable";
public static FAILURE_STRING_NO_GENERICS = "void is only valid as a return type";
public static FAILURE_WRONG_GENERIC = (genericName: string) =>
`${genericName} may not have void as a type variable`;

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithFunction(sourceFile, walk);
return this.applyWithFunction(sourceFile, walk, {
// tslint:disable-next-line:no-object-literal-type-assertion
allowGenerics: this.getAllowGenerics(this.ruleArguments[0] as RawOptions),
});
}

private getAllowGenerics(rawArgument: RawOptions) {
if (rawArgument == undefined) {
return true;
}

const allowGenerics = rawArgument[OPTION_ALLOW_GENERICS];

return allowGenerics instanceof Array ? new Set(allowGenerics) : Boolean(allowGenerics);
}
}

@@ -75,10 +124,60 @@ const failedKinds = new Set([
ts.SyntaxKind.CallExpression,
]);

function walk(ctx: Lint.WalkContext): void {
function walk(ctx: Lint.WalkContext<Options>): void {
const defaultFailureString = ctx.options.allowGenerics
? Rule.FAILURE_STRING_ALLOW_GENERICS
: Rule.FAILURE_STRING_NO_GENERICS;

const getGenericReferenceName = (node: GenericReference) => {
const rawName = tsutils.isNewExpression(node) ? node.expression : node.typeName;

return tsutils.isIdentifier(rawName) ? rawName.text : rawName.getText(ctx.sourceFile);
};

const getTypeReferenceFailure = (node: GenericReference) => {
if (!(ctx.options.allowGenerics instanceof Set)) {
return ctx.options.allowGenerics ? undefined : defaultFailureString;
}

const genericName = getGenericReferenceName(node);

return ctx.options.allowGenerics.has(genericName)
? undefined
: Rule.FAILURE_WRONG_GENERIC(genericName);
};

const checkTypeReference = (parent: GenericReference, node: ts.Node) => {
const failure = getTypeReferenceFailure(parent);

if (failure !== undefined) {
ctx.addFailureAtNode(node, failure);
}
};

const isParentGenericReference = (
parent: ts.Node,
node: ts.Node,
): parent is GenericReference => {
if (tsutils.isTypeReferenceNode(parent)) {
return true;
}

return (
tsutils.isNewExpression(parent) &&
parent.typeArguments !== undefined &&
ts.isTypeNode(node) &&
parent.typeArguments.indexOf(node) !== -1
);
};

ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node) {
if (node.kind === ts.SyntaxKind.VoidKeyword && failedKinds.has(node.parent.kind)) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
if (isParentGenericReference(node.parent, node)) {
checkTypeReference(node.parent, node);
} else {
ctx.addFailureAtNode(node, defaultFailureString);
}
}

ts.forEachChild(node, cb);
7 changes: 6 additions & 1 deletion src/rules/noUnnecessaryTypeAssertionRule.ts
Original file line number Diff line number Diff line change
@@ -44,13 +44,18 @@ export class Rule extends Lint.Rules.TypedRule {
"This assertion is unnecessary since it does not change the type of the expression.";

public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
const compilerOptions = program.getCompilerOptions();
const strictChecksEnabled = !!compilerOptions.strict;
const strictNullChecksEnabled = compilerOptions.strictNullChecks === true;
const strictNullChecksNotDisabled = compilerOptions.strictNullChecks !== false;

return this.applyWithWalker(
new Walker(
sourceFile,
this.ruleName,
this.ruleArguments,
program.getTypeChecker(),
!!program.getCompilerOptions().strictNullChecks,
strictNullChecksEnabled || (strictChecksEnabled && strictNullChecksNotDisabled),
),
);
}
Loading