runWithReporter method
Override this method to implement your lint rule.
Use context to register callbacks for AST node types:
context.addMethodInvocation((node) {
if (condition) {
reporter.atNode(node);
}
});
Implementation
@override
void runWithReporter(
SaropaDiagnosticReporter reporter,
SaropaContext context,
) {
// Use direct assignment expression callback for reliable detection
context.addAssignmentExpression((AssignmentExpression node) {
final lhs = node.leftHandSide;
// Only match variables ending with 'notifier'
if (lhs is! SimpleIdentifier) return;
final name = lhs.name.toLowerCase();
if (name != 'notifier' && !name.endsWith('notifier')) return;
// Check if file imports Riverpod - if not, skip entirely
if (!_fileImportsRiverpod(node)) return;
// Skip if inside a lifecycle method - initial construction is valid there
if (_isInsideLifecycleMethod(node)) return;
// Check if the RHS type is a Flutter notifier (not Riverpod)
final rhs = node.rightHandSide;
if (_isFlutterNotifierConstruction(rhs)) return;
// Check if the variable's declared type is a Flutter notifier
final declaredType = lhs.staticType?.getDisplayString();
if (declaredType != null && _isFlutterNotifierType(declaredType)) return;
// Also check RHS static type for cases where LHS type isn't resolved
final rhsType = rhs.staticType?.getDisplayString();
if (rhsType != null && _isFlutterNotifierType(rhsType)) return;
reporter.atNode(node);
});
}