@@ -30006,9 +30006,6 @@ namespace ts {
3000630006 workStacks.leftType[stackIndex] = leftType;
3000730007 const operator = node.operatorToken.kind;
3000830008 if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
30009- if (operator === SyntaxKind.AmpersandAmpersandToken) {
30010- checkTestingKnownTruthyCallableType(node.left, leftType);
30011- }
3001230009 checkTruthinessOfType(leftType, node.left);
3001330010 }
3001430011 advanceState(CheckBinaryExpressionState.FinishCheck);
@@ -30542,7 +30539,7 @@ namespace ts {
3054230539
3054330540 function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
3054430541 const type = checkTruthinessExpression(node.condition);
30545- checkTestingKnownTruthyCallableType(node.condition, type, node.whenTrue);
30542+ checkTestingKnownTruthyCallableType(node.condition, node.whenTrue, type );
3054630543 const type1 = checkExpression(node.whenTrue, checkMode);
3054730544 const type2 = checkExpression(node.whenFalse, checkMode);
3054830545 return getUnionType([type1, type2], UnionReduction.Subtype);
@@ -33778,7 +33775,7 @@ namespace ts {
3377833775 // Grammar checking
3377933776 checkGrammarStatementInAmbientContext(node);
3378033777 const type = checkTruthinessExpression(node.expression);
33781- checkTestingKnownTruthyCallableType(node.expression, type, node.thenStatement);
33778+ checkTestingKnownTruthyCallableType(node.expression, node.thenStatement, type );
3378233779 checkSourceElement(node.thenStatement);
3378333780
3378433781 if (node.thenStatement.kind === SyntaxKind.EmptyStatement) {
@@ -33788,16 +33785,16 @@ namespace ts {
3378833785 checkSourceElement(node.elseStatement);
3378933786 }
3379033787
33791- function checkTestingKnownTruthyCallableType(condExpr: Expression, type: Type, body? : Statement | Expression) {
33788+ function checkTestingKnownTruthyCallableType(condExpr: Expression, body: Statement | Expression, type: Type ) {
3379233789 if (!strictNullChecks) {
3379333790 return;
3379433791 }
3379533792
33796- const location = isBinaryExpression (condExpr) ? condExpr.right : condExpr;
33797- const testedNode = isIdentifier(location) ? location
33798- : isPropertyAccessExpression(location) ? location.name
33799- : isBinaryExpression(location) && isIdentifier(location.right) ? location.right
33800- : undefined;
33793+ const testedNode = isIdentifier (condExpr)
33794+ ? condExpr
33795+ : isPropertyAccessExpression(condExpr)
33796+ ? condExpr.name
33797+ : undefined;
3380133798
3380233799 if (!testedNode) {
3380333800 return;
@@ -33818,34 +33815,27 @@ namespace ts {
3381833815 return;
3381933816 }
3382033817
33821- const testedSymbol = getSymbolAtLocation(testedNode);
33822- if (!testedSymbol ) {
33818+ const testedFunctionSymbol = getSymbolAtLocation(testedNode);
33819+ if (!testedFunctionSymbol ) {
3382333820 return;
3382433821 }
3382533822
33826- const isUsed = isBinaryExpression(condExpr.parent) ? isFunctionUsedInBinaryExpressionChain(condExpr.parent, testedSymbol)
33827- : body ? isFunctionUsedInConditionBody(condExpr, body, testedNode, testedSymbol)
33828- : false;
33829- if (!isUsed) {
33830- error(location, Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
33831- }
33832- }
33833-
33834- function isFunctionUsedInConditionBody(expr: Expression, body: Statement | Expression, testedNode: Node, testedSymbol: Symbol): boolean {
33835- return !!forEachChild(body, function check(childNode): boolean | undefined {
33823+ const functionIsUsedInBody = forEachChild(body, function check(childNode): boolean | undefined {
3383633824 if (isIdentifier(childNode)) {
3383733825 const childSymbol = getSymbolAtLocation(childNode);
33838- if (childSymbol && childSymbol === testedSymbol ) {
33826+ if (childSymbol && childSymbol === testedFunctionSymbol ) {
3383933827 // If the test was a simple identifier, the above check is sufficient
33840- if (isIdentifier(expr )) {
33828+ if (isIdentifier(condExpr )) {
3384133829 return true;
3384233830 }
3384333831 // Otherwise we need to ensure the symbol is called on the same target
3384433832 let testedExpression = testedNode.parent;
3384533833 let childExpression = childNode.parent;
3384633834 while (testedExpression && childExpression) {
33835+
3384733836 if (isIdentifier(testedExpression) && isIdentifier(childExpression) ||
33848- testedExpression.kind === SyntaxKind.ThisKeyword && childExpression.kind === SyntaxKind.ThisKeyword) {
33837+ testedExpression.kind === SyntaxKind.ThisKeyword && childExpression.kind === SyntaxKind.ThisKeyword
33838+ ) {
3384933839 return getSymbolAtLocation(testedExpression) === getSymbolAtLocation(childExpression);
3385033840 }
3385133841
@@ -33862,18 +33852,13 @@ namespace ts {
3386233852 }
3386333853 }
3386433854 }
33855+
3386533856 return forEachChild(childNode, check);
3386633857 });
33867- }
3386833858
33869- function isFunctionUsedInBinaryExpressionChain(node: Node, testedSymbol: Symbol): boolean {
33870- while (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) {
33871- if (isCallExpression(node.right) && testedSymbol === getSymbolAtLocation(node.right.expression)) {
33872- return true;
33873- }
33874- node = node.parent;
33859+ if (!functionIsUsedInBody) {
33860+ error(condExpr, Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
3387533861 }
33876- return false;
3387733862 }
3387833863
3387933864 function checkDoStatement(node: DoStatement) {
0 commit comments