check method

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

Implementation

@override
void check(DcqRegistry registry) {
  final nullableParams = <int, List<_ParamInfo>>{};
  final callArgs = <int, List<_CallInfo>>{};

  void collectParams(int id, FormalParameterList? paramList) {
    if (paramList == null) return;
    final nullable = <_ParamInfo>[];
    var positionalIdx = 0;
    for (final p in paramList.parameters) {
      final isNamed = p.isNamed;
      final idx = isNamed ? -1 : positionalIdx;
      if (!isNamed) positionalIdx++;
      if (p.declaredFragment?.element.type.nullabilitySuffix ==
          NullabilitySuffix.question) {
        nullable.add(_ParamInfo(p, idx));
      }
    }
    if (nullable.isNotEmpty) nullableParams[id] = nullable;
  }

  registry.addFunctionDeclaration((node) {
    final element = node.declaredFragment?.element;
    if (element == null || !element.isPrivate) return;
    collectParams(element.id, node.functionExpression.parameters);
  });

  registry.addMethodDeclaration((node) {
    final element = node.declaredFragment?.element;
    if (element == null || !element.isPrivate) return;
    collectParams(element.id, node.parameters);
  });

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

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

      for (final info in entry.value) {
        final name = info.param.name?.lexeme;
        if (name == null) continue;

        final neverNull = calls.every((call) {
          final arg = call.findArg(
            name,
            info.param.isNamed,
            info.positionalIndex,
          );
          // If arg is omitted (optional), treat as null.
          if (arg == null) return info.param.isRequired;
          return arg is! NullLiteral;
        });

        if (neverNull) {
          reportAtNode(info.param);
        }
      }
    }
  });
}