Skip to content

Commit

Permalink
feat(rule): Add just rule and fixer.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Jun 3, 2018
1 parent f18f723 commit a34bd66
Show file tree
Hide file tree
Showing 27 changed files with 376 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"description": "TSLint rules for RxJS",
"devDependencies": {
"@phenomnomnominal/tsquery": "^1.0.5",
"@types/chai": "^4.0.0",
"@types/decamelize": "^1.2.0",
"@types/mocha": "^5.0.0",
Expand Down
94 changes: 94 additions & 0 deletions source/rules/rxjsJustRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* @license Use of this source code is governed by an MIT-style license that
* can be found in the LICENSE file at https://github.com/cartant/rxjs-tslint-rules
*/
/*tslint:disable:no-use-before-declare*/

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

import { tsquery } from "@phenomnomnominal/tsquery";
import { couldBeType } from "../support/util";

const defaultNamesRegExp = /^(canActivate|canActivateChild|canDeactivate|canLoad|intercept|resolve|validate)$/;
const defaultTypesRegExp = /^EventEmitter$/;

export class Rule extends Lint.Rules.TypedRule {

public static metadata: Lint.IRuleMetadata = {
description: "Enforces the use of a `just` alias for `of`.",
options: null,
optionsDescription: "Not configurable.",
requiresTypeInfo: true,
ruleName: "rxjs-just",
type: "style",
typescriptOnly: true
};

public static FAILURE_STRING = "Use just alias";

public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {

return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program));
}
}

class Walker extends Lint.ProgramAwareRuleWalker {

walk(sourceFile: ts.SourceFile): void {

const typeChecker = this.getTypeChecker();
let importIdentifier: ts.Identifier | undefined = undefined;

const importDeclarations = tsquery(
sourceFile,
`ImportDeclaration:has(StringLiteral[value="rxjs"]),ImportDeclaration:has(StringLiteral[value="rxjs/observable/of"])`
);
importDeclarations.forEach(importDeclaration => {
let importSpecifiers = tsquery(
importDeclaration,
`ImportSpecifier:has(Identifier[escapedText="of"])`
);
importSpecifiers.forEach(importSpecifier => {
if (tsutils.isImportSpecifier(importSpecifier)) {
if (!importSpecifier.propertyName && (importSpecifier.name.getText() === "of")) {
importIdentifier = importSpecifier.name;
const fix = Lint.Replacement.replaceFromTo(
importIdentifier.getStart(),
importIdentifier.getStart() + importIdentifier.getWidth(),
"of as just"
);
this.addFailureAtNode(importIdentifier, Rule.FAILURE_STRING, fix);
}
}
});
});

if (importIdentifier) {
const callExpressions = tsquery(
sourceFile,
`CallExpression:has(Identifier[escapedText="of"])`
);
callExpressions.forEach(callExpression => {
if (tsutils.isCallExpression(callExpression)) {
const expression = callExpression.expression;
if (tsutils.isIdentifier(expression)) {

const symbol = typeChecker.getSymbolAtLocation(expression);
const [declaration] = symbol.getDeclarations();

if (declaration === importIdentifier.parent) {
const fix = Lint.Replacement.replaceFromTo(
expression.getStart(),
expression.getStart() + expression.getWidth(),
"just"
);
this.addFailureAtNode(expression, Rule.FAILURE_STRING, fix);
}
}
}
});
}
}
}
4 changes: 4 additions & 0 deletions test/v5/fixtures/just/default/fixture.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { of as just } from "rxjs/observable/of";

const a = just("a");

7 changes: 7 additions & 0 deletions test/v5/fixtures/just/default/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { of } from "rxjs/observable/of";
~~ [just]

const a = of("a");
~~ [just]

[just]: Use just alias
13 changes: 13 additions & 0 deletions test/v5/fixtures/just/default/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
8 changes: 8 additions & 0 deletions test/v5/fixtures/just/default/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-just": { "severity": "error" }
},
"rulesDirectory": "../../../../../build/rules"
}
16 changes: 16 additions & 0 deletions test/v5/fixtures/just/user-land/fixture.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { of as just } from "rxjs/observable/of";

function foo(): void {
function of(): void {}
of();
}

function bar(of: Function): void {
of();
}

function baz(): void {
const of = () => {};
of();
}

18 changes: 18 additions & 0 deletions test/v5/fixtures/just/user-land/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { of } from "rxjs/observable/of";
~~ [just]

function foo(): void {
function of(): void {}
of();
}

function bar(of: Function): void {
of();
}

function baz(): void {
const of = () => {};
of();
}

[just]: Use just alias
13 changes: 13 additions & 0 deletions test/v5/fixtures/just/user-land/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
8 changes: 8 additions & 0 deletions test/v5/fixtures/just/user-land/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-just": { "severity": "error" }
},
"rulesDirectory": "../../../../../build/rules"
}
4 changes: 4 additions & 0 deletions test/v6-compat/fixtures/just/default/fixture.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { of as just } from "rxjs/observable/of";

const a = just("a");

7 changes: 7 additions & 0 deletions test/v6-compat/fixtures/just/default/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { of } from "rxjs/observable/of";
~~ [just]

const a = of("a");
~~ [just]

[just]: Use just alias
13 changes: 13 additions & 0 deletions test/v6-compat/fixtures/just/default/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
8 changes: 8 additions & 0 deletions test/v6-compat/fixtures/just/default/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-just": { "severity": "error" }
},
"rulesDirectory": "../../../../../build/rules"
}
16 changes: 16 additions & 0 deletions test/v6-compat/fixtures/just/user-land/fixture.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { of as just } from "rxjs/observable/of";

function foo(): void {
function of(): void {}
of();
}

function bar(of: Function): void {
of();
}

function baz(): void {
const of = () => {};
of();
}

18 changes: 18 additions & 0 deletions test/v6-compat/fixtures/just/user-land/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { of } from "rxjs/observable/of";
~~ [just]

function foo(): void {
function of(): void {}
of();
}

function bar(of: Function): void {
of();
}

function baz(): void {
const of = () => {};
of();
}

[just]: Use just alias
13 changes: 13 additions & 0 deletions test/v6-compat/fixtures/just/user-land/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
8 changes: 8 additions & 0 deletions test/v6-compat/fixtures/just/user-land/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-just": { "severity": "error" }
},
"rulesDirectory": "../../../../../build/rules"
}
4 changes: 4 additions & 0 deletions test/v6/fixtures/just/default/fixture.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { of as just } from "rxjs";

const a = just("a");

7 changes: 7 additions & 0 deletions test/v6/fixtures/just/default/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { of } from "rxjs";
~~ [just]

const a = of("a");
~~ [just]

[just]: Use just alias
13 changes: 13 additions & 0 deletions test/v6/fixtures/just/default/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
8 changes: 8 additions & 0 deletions test/v6/fixtures/just/default/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-just": { "severity": "error" }
},
"rulesDirectory": "../../../../../build/rules"
}
16 changes: 16 additions & 0 deletions test/v6/fixtures/just/user-land/fixture.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { of as just } from "rxjs";

function foo(): void {
function of(): void {}
of();
}

function bar(of: Function): void {
of();
}

function baz(): void {
const of = () => {};
of();
}

18 changes: 18 additions & 0 deletions test/v6/fixtures/just/user-land/fixture.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { of } from "rxjs";
~~ [just]

function foo(): void {
function of(): void {}
of();
}

function bar(of: Function): void {
of();
}

function baz(): void {
const of = () => {};
of();
}

[just]: Use just alias
13 changes: 13 additions & 0 deletions test/v6/fixtures/just/user-land/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"lib": ["es2015"],
"noEmit": true,
"paths": {
"rxjs": ["../../node_modules/rxjs"]
},
"skipLibCheck": true,
"target": "es5"
},
"include": ["fixture.ts"]
}
8 changes: 8 additions & 0 deletions test/v6/fixtures/just/user-land/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"rxjs-just": { "severity": "error" }
},
"rulesDirectory": "../../../../../build/rules"
}
Loading

0 comments on commit a34bd66

Please sign in to comment.