@@ -30006,9 +30006,6 @@ namespace ts {
30006
30006
workStacks.leftType[stackIndex] = leftType;
30007
30007
const operator = node.operatorToken.kind;
30008
30008
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
30009
- if (operator === SyntaxKind.AmpersandAmpersandToken) {
30010
- checkTestingKnownTruthyCallableType(node.left, leftType);
30011
- }
30012
30009
checkTruthinessOfType(leftType, node.left);
30013
30010
}
30014
30011
advanceState(CheckBinaryExpressionState.FinishCheck);
@@ -30542,7 +30539,7 @@ namespace ts {
30542
30539
30543
30540
function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
30544
30541
const type = checkTruthinessExpression(node.condition);
30545
- checkTestingKnownTruthyCallableType(node.condition, type, node.whenTrue);
30542
+ checkTestingKnownTruthyCallableType(node.condition, node.whenTrue, type );
30546
30543
const type1 = checkExpression(node.whenTrue, checkMode);
30547
30544
const type2 = checkExpression(node.whenFalse, checkMode);
30548
30545
return getUnionType([type1, type2], UnionReduction.Subtype);
@@ -33778,7 +33775,7 @@ namespace ts {
33778
33775
// Grammar checking
33779
33776
checkGrammarStatementInAmbientContext(node);
33780
33777
const type = checkTruthinessExpression(node.expression);
33781
- checkTestingKnownTruthyCallableType(node.expression, type, node.thenStatement);
33778
+ checkTestingKnownTruthyCallableType(node.expression, node.thenStatement, type );
33782
33779
checkSourceElement(node.thenStatement);
33783
33780
33784
33781
if (node.thenStatement.kind === SyntaxKind.EmptyStatement) {
@@ -33788,16 +33785,16 @@ namespace ts {
33788
33785
checkSourceElement(node.elseStatement);
33789
33786
}
33790
33787
33791
- function checkTestingKnownTruthyCallableType(condExpr: Expression, type: Type, body? : Statement | Expression) {
33788
+ function checkTestingKnownTruthyCallableType(condExpr: Expression, body: Statement | Expression, type: Type ) {
33792
33789
if (!strictNullChecks) {
33793
33790
return;
33794
33791
}
33795
33792
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;
33801
33798
33802
33799
if (!testedNode) {
33803
33800
return;
@@ -33818,34 +33815,27 @@ namespace ts {
33818
33815
return;
33819
33816
}
33820
33817
33821
- const testedSymbol = getSymbolAtLocation(testedNode);
33822
- if (!testedSymbol ) {
33818
+ const testedFunctionSymbol = getSymbolAtLocation(testedNode);
33819
+ if (!testedFunctionSymbol ) {
33823
33820
return;
33824
33821
}
33825
33822
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 {
33836
33824
if (isIdentifier(childNode)) {
33837
33825
const childSymbol = getSymbolAtLocation(childNode);
33838
- if (childSymbol && childSymbol === testedSymbol ) {
33826
+ if (childSymbol && childSymbol === testedFunctionSymbol ) {
33839
33827
// If the test was a simple identifier, the above check is sufficient
33840
- if (isIdentifier(expr )) {
33828
+ if (isIdentifier(condExpr )) {
33841
33829
return true;
33842
33830
}
33843
33831
// Otherwise we need to ensure the symbol is called on the same target
33844
33832
let testedExpression = testedNode.parent;
33845
33833
let childExpression = childNode.parent;
33846
33834
while (testedExpression && childExpression) {
33835
+
33847
33836
if (isIdentifier(testedExpression) && isIdentifier(childExpression) ||
33848
- testedExpression.kind === SyntaxKind.ThisKeyword && childExpression.kind === SyntaxKind.ThisKeyword) {
33837
+ testedExpression.kind === SyntaxKind.ThisKeyword && childExpression.kind === SyntaxKind.ThisKeyword
33838
+ ) {
33849
33839
return getSymbolAtLocation(testedExpression) === getSymbolAtLocation(childExpression);
33850
33840
}
33851
33841
@@ -33862,18 +33852,13 @@ namespace ts {
33862
33852
}
33863
33853
}
33864
33854
}
33855
+
33865
33856
return forEachChild(childNode, check);
33866
33857
});
33867
- }
33868
33858
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);
33875
33861
}
33876
- return false;
33877
33862
}
33878
33863
33879
33864
function checkDoStatement(node: DoStatement) {
0 commit comments