analyze method

Future<List<FutureCallDefinition>> analyze({
  1. required CodeAnalysisCollector collector,
  2. Set<String>? changedFiles,
})

Analyze all files in the AnalysisContextCollection.

changedFiles is an optional list of files that should have their context refreshed before analysis. This is useful when only a subset of files have changed since updateFileContexts was last called.

Implementation

Future<List<FutureCallDefinition>> analyze({
  required CodeAnalysisCollector collector,
  Set<String>? changedFiles,
}) async {
  await _refreshContextForFiles(changedFiles);

  var futureCallDefs = <FutureCallDefinition>[];

  List<(ResolvedLibraryResult, String)> validLibraries = [];
  Map<String, int> futureCallClassMap = {};

  final templateRegistry = DartDocTemplateRegistry();

  await for (var (library, filePath) in _libraries) {
    var futureCallClasses = _getFutureCallClasses(library);
    if (futureCallClasses.isEmpty) continue;

    var maybeDartErrors = await _getErrorsForFile(library.session, filePath);
    if (maybeDartErrors.isNotEmpty) {
      collector.addError(
        SourceSpanSeverityException(
          'FutureCall analysis skipped due to invalid Dart syntax. Please '
          'review and correct the syntax errors.'
          '\nFile: $filePath',
          null,
          severity: SourceSpanSeverity.error,
        ),
      );

      continue;
    }

    for (var futureCallClass in futureCallClasses) {
      var className = futureCallClass.name!;
      futureCallClassMap.update(
        className,
        (value) => value + 1,
        ifAbsent: () => 1,
      );
    }

    validLibraries.add((library, filePath));
  }

  var duplicateFutureCallClasses = futureCallClassMap.entries
      .where((entry) => entry.value > 1)
      .map((entry) => entry.key)
      .toSet();

  for (var (library, filePath) in validLibraries) {
    var severityExceptions = _validateLibrary(
      library,
      filePath,
      duplicateFutureCallClasses,
    );
    collector.addErrors(severityExceptions.values.expand((e) => e).toList());

    var failingExceptions = _filterNoFailExceptions(severityExceptions);

    futureCallDefs.addAll(
      _parseLibrary(
        library,
        filePath,
        failingExceptions,
        templateRegistry: templateRegistry,
      ),
    );
  }

  // After parsing all future calls, we must remove all that are not part of
  // this package to avoid generating them as well.
  futureCallDefs.removeWhere((e) => e.filePath.startsWith('package:'));

  _futureCallDefinitions = futureCallDefs.toSet();
  return futureCallDefs;
}