in lib/src/rules/use_build_context_synchronously.dart [187:262]
bool isMountedCheck(Statement statement, {bool positiveCheck = false}) {
// This is intentionally naive. Using a simple 'mounted' property check
// as a signal plays nicely w/ unanticipated framework classes that provide
// their own mounted checks. The cost of this generality is the possibility
// of false negatives.
if (statement is IfStatement) {
var condition = statement.condition;
Expression check;
if (condition is PrefixExpression) {
if (positiveCheck && condition.isNot) {
return false;
}
check = condition.operand;
} else {
check = condition;
}
bool checksMounted(Expression check) {
if (check is BinaryExpression) {
// (condition && context.mounted)
if (positiveCheck) {
if (check.isAnd) {
return checksMounted(check.leftOperand) ||
checksMounted(check.rightOperand);
}
} else {
// (condition || !mounted)
if (check.isOr) {
return checksMounted(check.leftOperand) ||
checksMounted(check.rightOperand);
}
}
}
// stateContext.mounted => mounted
if (check is PrefixedIdentifier) {
// ignore: parameter_assignments
check = check.identifier;
}
if (check is SimpleIdentifier) {
return check.name == 'mounted';
}
if (check is PrefixExpression) {
// (condition || !mounted)
if (!positiveCheck && check.isNot) {
return checksMounted(check.operand);
}
}
return false;
}
if (checksMounted(check)) {
// In the positive case it's sufficient to know we're in a positively
// guarded block.
if (positiveCheck) {
return true;
}
var then = statement.thenStatement;
return terminatesControl(then);
}
} else if (statement is TryStatement) {
var statements = statement.finallyBlock?.statements;
if (statements == null) {
return false;
}
for (var i = statements.length - 1; i >= 0; i--) {
var s = statements[i];
if (isMountedCheck(s)) {
return true;
}
}
}
return false;
}