Skip to content

Commit

Permalink
fix: Fix no-redundant-notify false positives.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Nov 15, 2019
1 parent 9787bf9 commit c08c919
Showing 1 changed file with 50 additions and 2 deletions.
52 changes: 50 additions & 2 deletions source/rules/rxjsNoRedundantNotifyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { tsquery } from "@phenomnomnominal/tsquery";
import * as Lint from "tslint";
import * as ts from "typescript";
import { couldBeType } from "../support/util";

export class Rule extends Lint.Rules.TypedRule {
public static metadata: Lint.IRuleMetadata = {
Expand All @@ -26,10 +27,27 @@ export class Rule extends Lint.Rules.TypedRule {
program: ts.Program
): Lint.RuleFailure[] {
const failures: Lint.RuleFailure[] = [];
const typeChecker = program.getTypeChecker();
const query = `ExpressionStatement[expression.expression.name.text=/^(complete|error)$/] ~ ExpressionStatement[expression.expression.name.text=/^(next|complete|error)$/]`;
const expressionStatements = tsquery(sourceFile, query);
expressionStatements.forEach(node => {
const expressionStatement = node as ts.ExpressionStatement;
expressionStatements.forEach((node: ts.ExpressionStatement) => {
const { parent } = node;
if (!ts.isBlock(parent)) {
return;
}
const { statements } = parent;
const index = statements.indexOf(node);
const sibling = statements[index - 1] as ts.ExpressionStatement;
if (
!isExpressionObservable(sibling, typeChecker) ||
!isExpressionObservable(node, typeChecker)
) {
return;
}
if (getExpressionText(sibling) !== getExpressionText(node)) {
return;
}
const expressionStatement = node;
if (ts.isCallExpression(expressionStatement.expression)) {
const callExpression = expressionStatement.expression;
if (ts.isPropertyAccessExpression(callExpression.expression)) {
Expand All @@ -49,3 +67,33 @@ export class Rule extends Lint.Rules.TypedRule {
return failures;
}
}

function getExpressionText(
expressionStatement: ts.ExpressionStatement
): string | undefined {
if (!ts.isCallExpression(expressionStatement.expression)) {
return undefined;
}
const callExpression = expressionStatement.expression;
if (!ts.isPropertyAccessExpression(callExpression.expression)) {
return undefined;
}
const { expression } = callExpression.expression;
return expression.getText();
}

function isExpressionObservable(
expressionStatement: ts.ExpressionStatement,
typeChecker: ts.TypeChecker
): boolean {
if (!ts.isCallExpression(expressionStatement.expression)) {
return false;
}
const callExpression = expressionStatement.expression;
if (!ts.isPropertyAccessExpression(callExpression.expression)) {
return false;
}
const { expression } = callExpression.expression;
const type = typeChecker.getTypeAtLocation(expression);
return couldBeType(type, /^(Subject|Subscriber)$/);
}

0 comments on commit c08c919

Please sign in to comment.