(condExpr, body)
| 82697 | helper(condExpr, body); |
| 82698 | } |
| 82699 | function helper(condExpr, body) { |
| 82700 | var location = ts.isBinaryExpression(condExpr) && |
| 82701 | (condExpr.operatorToken.kind === 56 /* SyntaxKind.BarBarToken */ || condExpr.operatorToken.kind === 55 /* SyntaxKind.AmpersandAmpersandToken */) |
| 82702 | ? condExpr.right |
| 82703 | : condExpr; |
| 82704 | if (ts.isModuleExportsAccessExpression(location)) |
| 82705 | return; |
| 82706 | var type = checkTruthinessExpression(location); |
| 82707 | var isPropertyExpressionCast = ts.isPropertyAccessExpression(location) && isTypeAssertion(location.expression); |
| 82708 | if (getFalsyFlags(type) || isPropertyExpressionCast) |
| 82709 | return; |
| 82710 | // While it technically should be invalid for any known-truthy value |
| 82711 | // to be tested, we de-scope to functions and Promises unreferenced in |
| 82712 | // the block as a heuristic to identify the most common bugs. There |
| 82713 | // are too many false positives for values sourced from type |
| 82714 | // definitions without strictNullChecks otherwise. |
| 82715 | var callSignatures = getSignaturesOfType(type, 0 /* SignatureKind.Call */); |
| 82716 | var isPromise = !!getAwaitedTypeOfPromise(type); |
| 82717 | if (callSignatures.length === 0 && !isPromise) { |
| 82718 | return; |
| 82719 | } |
| 82720 | var testedNode = ts.isIdentifier(location) ? location |
| 82721 | : ts.isPropertyAccessExpression(location) ? location.name |
| 82722 | : ts.isBinaryExpression(location) && ts.isIdentifier(location.right) ? location.right |
| 82723 | : undefined; |
| 82724 | var testedSymbol = testedNode && getSymbolAtLocation(testedNode); |
| 82725 | if (!testedSymbol && !isPromise) { |
| 82726 | return; |
| 82727 | } |
| 82728 | var isUsed = testedSymbol && ts.isBinaryExpression(condExpr.parent) && isSymbolUsedInBinaryExpressionChain(condExpr.parent, testedSymbol) |
| 82729 | || testedSymbol && body && isSymbolUsedInConditionBody(condExpr, body, testedNode, testedSymbol); |
| 82730 | if (!isUsed) { |
| 82731 | if (isPromise) { |
| 82732 | errorAndMaybeSuggestAwait(location, |
| 82733 | /*maybeMissingAwait*/ true, ts.Diagnostics.This_condition_will_always_return_true_since_this_0_is_always_defined, getTypeNameForErrorDisplay(type)); |
| 82734 | } |
| 82735 | else { |
| 82736 | error(location, ts.Diagnostics.This_condition_will_always_return_true_since_this_function_is_always_defined_Did_you_mean_to_call_it_instead); |
| 82737 | } |
| 82738 | } |
| 82739 | } |
| 82740 | } |
| 82741 | function isSymbolUsedInConditionBody(expr, body, testedNode, testedSymbol) { |
| 82742 | return !!ts.forEachChild(body, function check(childNode) { |
no test coverage detected