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,
) {
context.addConstructorDeclaration((ConstructorDeclaration node) {
// Skip redirecting constructors (factory Foo(int x) = _Foo)
if (node.redirectedConstructor != null) return;
final FormalParameterList? params = node.parameters;
if (params == null) return;
// Collect body source for reference checking
final String bodySource = node.body.toSource();
// Collect initializer list source
final String initSource = node.initializers
.map((ConstructorInitializer i) => i.toSource())
.join(' ');
for (final FormalParameter param in params.parameters) {
// this.field and super.field are always "used"
if (param is FieldFormalParameter) continue;
if (param is SuperFormalParameter) continue;
// Get the actual parameter (unwrap DefaultFormalParameter)
final FormalParameter actual = param is DefaultFormalParameter
? param.parameter
: param;
if (actual is FieldFormalParameter) continue;
if (actual is SuperFormalParameter) continue;
final String? name = _paramName(actual);
if (name == null || name.startsWith('_')) continue;
// Check if referenced in initializer list or body
final RegExp ref = RegExp('\\b${RegExp.escape(name)}\\b');
if (ref.hasMatch(initSource)) continue;
if (bodySource != ';' && ref.hasMatch(bodySource)) continue;
reporter.atNode(param);
}
});
}