mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Improve uncalled function checks (#41599)
Fixes #41586 Fixes #41588 1. For binary expressions, if the immediate parent is an IfStatement, then check the body of the if statement. I didn't walk upward to find an IfStatement because in my experimentation I found that binary expression uncalled-function errors are only issued when the expression is on the left of the top-most binary expression. 2. For property accesses with interspersed calls, I added a CallExpression case. In fact, any expression could appear here, but I only want to fix calls for now since that's all we've observed in Definitely Typed, and we didn't see anything else in the user tests or RWC tests. I also didn't examine parameters of the intermediate call expressions, but I don't think it's needed since the intent is to avoid false positives.
This commit is contained in:
committed by
GitHub
parent
23b3eb685f
commit
06fb724cd1
@@ -30185,7 +30185,7 @@ namespace ts {
|
||||
const operator = node.operatorToken.kind;
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken) {
|
||||
checkTestingKnownTruthyCallableType(node.left, leftType);
|
||||
checkTestingKnownTruthyCallableType(node.left, leftType, isIfStatement(node.parent) ? node.parent.thenStatement : undefined);
|
||||
}
|
||||
checkTruthinessOfType(leftType, node.left);
|
||||
}
|
||||
@@ -33972,7 +33972,7 @@ namespace ts {
|
||||
checkSourceElement(node.elseStatement);
|
||||
}
|
||||
|
||||
function checkTestingKnownTruthyCallableType(condExpr: Expression, type: Type, body?: Statement | Expression) {
|
||||
function checkTestingKnownTruthyCallableType(condExpr: Expression, type: Type, body: Statement | Expression | undefined) {
|
||||
if (!strictNullChecks) {
|
||||
return;
|
||||
}
|
||||
@@ -34007,9 +34007,8 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const isUsed = isBinaryExpression(condExpr.parent) ? isFunctionUsedInBinaryExpressionChain(condExpr.parent, testedSymbol)
|
||||
: body ? isFunctionUsedInConditionBody(condExpr, body, testedNode, testedSymbol)
|
||||
: false;
|
||||
const isUsed = isBinaryExpression(condExpr.parent) && isFunctionUsedInBinaryExpressionChain(condExpr.parent, testedSymbol)
|
||||
|| body && isFunctionUsedInConditionBody(condExpr, body, testedNode, testedSymbol);
|
||||
if (!isUsed) {
|
||||
error(location, Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
|
||||
}
|
||||
@@ -34032,14 +34031,17 @@ namespace ts {
|
||||
testedExpression.kind === SyntaxKind.ThisKeyword && childExpression.kind === SyntaxKind.ThisKeyword) {
|
||||
return getSymbolAtLocation(testedExpression) === getSymbolAtLocation(childExpression);
|
||||
}
|
||||
|
||||
if (isPropertyAccessExpression(testedExpression) && isPropertyAccessExpression(childExpression)) {
|
||||
else if (isPropertyAccessExpression(testedExpression) && isPropertyAccessExpression(childExpression)) {
|
||||
if (getSymbolAtLocation(testedExpression.name) !== getSymbolAtLocation(childExpression.name)) {
|
||||
return false;
|
||||
}
|
||||
childExpression = childExpression.expression;
|
||||
testedExpression = testedExpression.expression;
|
||||
}
|
||||
else if (isCallExpression(testedExpression) && isCallExpression(childExpression)) {
|
||||
childExpression = childExpression.expression;
|
||||
testedExpression = testedExpression.expression;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user