run method

  1. @override
void run(
  1. CustomLintResolver resolver,
  2. DiagnosticReporter reporter,
  3. CustomLintContext context
)

Emits lints for a given file.

run will only be invoked with files respecting filesToAnalyze

Implementation

@override
void run(
  CustomLintResolver resolver,
  DiagnosticReporter reporter,
  CustomLintContext context,
) {
  if (isGeneratedFile(resolver.path)) return;
  if (!RigidConfig.forFile(resolver.path).isEnabled(code.name)) return;

  context.registry.addClassDeclaration((node) {
    // Collect field names that are disposable.
    final disposableFields = <String>{};

    for (final member in node.members) {
      if (member is FieldDeclaration) {
        for (final variable in member.fields.variables) {
          final type = variable.declaredFragment?.element.type;
          if (type != null && _disposableTypes.isAssignableFromType(type)) {
            disposableFields.add(variable.name.lexeme);
          }
        }
      }
    }

    if (disposableFields.isEmpty) return;

    // Find dispose() method and check what it disposes.
    final disposedFields = <String>{};
    for (final member in node.members) {
      if (member is MethodDeclaration && member.name.lexeme == 'dispose') {
        member.accept(_DisposeFinder(disposedFields));
      }
    }

    // Report fields that are not disposed.
    for (final member in node.members) {
      if (member is FieldDeclaration) {
        for (final variable in member.fields.variables) {
          final name = variable.name.lexeme;
          if (disposableFields.contains(name) &&
              !disposedFields.contains(name)) {
            reporter.atNode(variable, code);
          }
        }
      }
    }
  });
}