check method

  1. @override
void check(
  1. DcqRegistry registry
)

Implementation

@override
void check(DcqRegistry registry) {
  // Collect private function/method declarations and their call sites.
  // Key: element id, Value: (declaration params, call arg info).
  final paramDecls = <int, List<FormalParameter>>{};
  final callArgs = <int, List<_CallInfo>>{};

  registry.addFunctionDeclaration((node) {
    final element = node.declaredFragment?.element;
    if (element == null) return;
    if (!element.isPrivate) return;
    final id = element.id;
    paramDecls[id] = node.functionExpression.parameters?.parameters ?? [];
  });

  registry.addMethodDeclaration((node) {
    final element = node.declaredFragment?.element;
    if (element == null) return;
    if (!element.isPrivate) return;
    final id = element.id;
    paramDecls[id] = node.parameters?.parameters ?? [];
  });

  registry.addMethodInvocation((node) {
    final element = node.methodName.element;
    if (element is! ExecutableElement) return;
    if (!element.isPrivate) return;
    callArgs
        .putIfAbsent(element.id, () => [])
        .add(
          _CallInfo(node.argumentList),
        );
  });

  registry.addFunctionExpressionInvocation((node) {
    final fn = node.function;
    if (fn is! SimpleIdentifier) return;
    final element = fn.element;
    if (element is! ExecutableElement) return;
    if (!element.isPrivate) return;
    callArgs
        .putIfAbsent(element.id, () => [])
        .add(
          _CallInfo(node.argumentList),
        );
  });

  registry.afterLibrary(() {
    for (final entry in paramDecls.entries) {
      final id = entry.key;
      final params = entry.value;
      final calls = callArgs[id];
      if (calls == null || calls.isEmpty) continue;

      for (var i = 0; i < params.length; i++) {
        final param = params[i];
        final paramName = param.name?.lexeme;
        if (paramName == null) continue;

        final alwaysNull = calls.every((call) {
          final arg = call.argumentFor(i, paramName);
          if (arg == null) {
            // Omitted optional parameter — effectively null if no default
            // or default is null.
            return _hasNullDefault(param);
          }
          return arg is NullLiteral;
        });

        if (alwaysNull) {
          reportAtNode(param);
        }
      }
    }
  });
}