// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart' as file_state;
import 'package:analyzer/src/dart/analysis/testing_data.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/constant/compute.dart';
import 'package:analyzer/src/dart/constant/constant_verifier.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/constant/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
import 'package:analyzer/src/dart/resolver/resolution_visitor.dart';
import 'package:analyzer/src/error/best_practices_verifier.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/error/dead_code_verifier.dart';
import 'package:analyzer/src/error/ignore_validator.dart';
import 'package:analyzer/src/error/imports_verifier.dart';
import 'package:analyzer/src/error/inheritance_override.dart';
import 'package:analyzer/src/error/language_version_override_verifier.dart';
import 'package:analyzer/src/error/override_verifier.dart';
import 'package:analyzer/src/error/todo_finder.dart';
import 'package:analyzer/src/error/unicode_text_verifier.dart';
import 'package:analyzer/src/error/unused_local_elements_verifier.dart';
import 'package:analyzer/src/generated/element_walker.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error_verifier.dart';
import 'package:analyzer/src/generated/ffi_verifier.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/hint/sdk_constraint_verifier.dart';
import 'package:analyzer/src/ignore_comments/ignore_info.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/linter_visitor.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/task/strong/checker.dart';
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:collection/collection.dart';

class AnalysisForCompletionResult {
  final CompilationUnit parsedUnit;
  final List<AstNode> resolvedNodes;

  AnalysisForCompletionResult({
    required this.parsedUnit,
    required this.resolvedNodes,
  });
}

/// Analyzer of a single library.
class LibraryAnalyzer {
  final AnalysisOptionsImpl _analysisOptions;
  final DeclaredVariables _declaredVariables;
  final LibraryFileStateKind _library;
  final InheritanceManager3 _inheritance;

  final LibraryElementImpl _libraryElement;

  final Map<FileState, LineInfo> _fileToLineInfo = {};

  final Map<FileState, IgnoreInfo> _fileToIgnoreInfo = {};
  final Map<FileState, RecordingErrorListener> _errorListeners = {};
  final Map<FileState, ErrorReporter> _errorReporters = {};
  final TestingData? _testingData;

  LibraryAnalyzer(this._analysisOptions, this._declaredVariables,
      this._libraryElement, this._inheritance, this._library,
      {TestingData? testingData})
      : _testingData = testingData;

  TypeProviderImpl get _typeProvider => _libraryElement.typeProvider;

  TypeSystemImpl get _typeSystem => _libraryElement.typeSystem;

  /// Compute analysis results for all units of the library.
  List<UnitAnalysisResult> analyze() {
    var units = _parseAndResolve();
    _computeDiagnostics(units);

    // Return full results.
    var results = <UnitAnalysisResult>[];
    units.forEach((file, unit) {
      List<AnalysisError> errors = _getErrorListener(file).errors;
      errors = _filterIgnoredErrors(file, errors);
      results.add(UnitAnalysisResult(file, unit, errors));
    });
    return results;
  }

  /// Analyze [file] for a completion result.
  ///
  /// This method aims to avoid work that [analyze] does which would be
  /// unnecessary for a completion request.
  AnalysisForCompletionResult analyzeForCompletion({
    required FileState file,
    required int offset,
    required CompilationUnitElementImpl unitElement,
    required OperationPerformanceImpl performance,
  }) {
    var parsedUnit = performance.run('parse', (performance) {
      return _parse(file);
    });

    var node = NodeLocator(offset).searchWithin(parsedUnit);

    if (_hasEmptyCompletionContext(node)) {
      return AnalysisForCompletionResult(
        parsedUnit: parsedUnit,
        resolvedNodes: [],
      );
    }

    var errorListener = RecordingErrorListener();

    return performance.run('resolve', (performance) {
      // TODO(scheglov) We don't need to do this for the whole unit.
      parsedUnit.accept(
        ResolutionVisitor(
          unitElement: unitElement,
          errorListener: errorListener,
          featureSet: _libraryElement.featureSet,
          nameScope: _libraryElement.scope,
          elementWalker: ElementWalker.forCompilationUnit(
            unitElement,
            libraryFilePath: _library.file.path,
            unitFilePath: file.path,
          ),
        ),
      );

      // TODO(scheglov) We don't need to do this for the whole unit.
      parsedUnit.accept(ScopeResolverVisitor(
          _libraryElement, file.source, _typeProvider, errorListener,
          nameScope: _libraryElement.scope));

      FlowAnalysisHelper flowAnalysisHelper = FlowAnalysisHelper(
          _typeSystem, _testingData != null, _libraryElement.featureSet);
      _testingData?.recordFlowAnalysisDataForTesting(
          file.uri, flowAnalysisHelper.dataForTesting!);

      var resolverVisitor = ResolverVisitor(_inheritance, _libraryElement,
          file.source, _typeProvider, errorListener,
          featureSet: _libraryElement.featureSet,
          flowAnalysisHelper: flowAnalysisHelper);

      var nodeToResolve = node?.thisOrAncestorMatching((e) {
        return e.parent is ClassDeclaration ||
            e.parent is CompilationUnit ||
            e.parent is ExtensionDeclaration ||
            e.parent is MixinDeclaration;
      });
      if (nodeToResolve != null) {
        var canResolveNode = resolverVisitor.prepareForResolving(nodeToResolve);
        if (canResolveNode) {
          nodeToResolve.accept(resolverVisitor);
          return AnalysisForCompletionResult(
            parsedUnit: parsedUnit,
            resolvedNodes: [nodeToResolve],
          );
        }
      }

      var units = _parseAndResolve();
      var unit = units[file]!;
      return AnalysisForCompletionResult(
        parsedUnit: unit,
        resolvedNodes: [unit],
      );
    });
  }

  void _checkForInconsistentLanguageVersionOverride(
    Map<FileState, CompilationUnit> units,
  ) {
    var libraryEntry = units.entries.first;
    var libraryUnit = libraryEntry.value;
    var libraryOverrideToken = libraryUnit.languageVersionToken;

    var elementToUnit = <CompilationUnitElement, CompilationUnit>{};
    for (var entry in units.entries) {
      var unit = entry.value;
      elementToUnit[unit.declaredElement!] = unit;
    }

    for (var directive in libraryUnit.directives) {
      if (directive is PartDirective) {
        var partUnit = elementToUnit[directive.uriElement];
        if (partUnit != null) {
          var shouldReport = false;
          var partOverrideToken = partUnit.languageVersionToken;
          if (libraryOverrideToken != null) {
            if (partOverrideToken != null) {
              if (partOverrideToken.major != libraryOverrideToken.major ||
                  partOverrideToken.minor != libraryOverrideToken.minor) {
                shouldReport = true;
              }
            } else {
              shouldReport = true;
            }
          } else if (partOverrideToken != null) {
            shouldReport = true;
          }
          if (shouldReport) {
            _getErrorReporter(_library.file).reportErrorForNode(
              CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE,
              directive.uri,
            );
          }
        }
      }
    }
  }

  void _computeConstantErrors(
      ErrorReporter errorReporter, CompilationUnit unit) {
    ConstantVerifier constantVerifier =
        ConstantVerifier(errorReporter, _libraryElement, _declaredVariables);
    unit.accept(constantVerifier);
  }

  /// Compute [_constants] in all units.
  void _computeConstants(Iterable<CompilationUnitImpl> units) {
    var constants = [
      for (var unit in units) ..._findConstants(unit),
    ];
    computeConstants(_declaredVariables, constants, _libraryElement.featureSet);
  }

  /// Compute diagnostics in [units], including errors and warnings, hints,
  /// lints, and a few other cases.
  void _computeDiagnostics(Map<FileState, CompilationUnitImpl> units) {
    units.forEach((file, unit) {
      _computeVerifyErrors(file, unit);
    });

    if (_analysisOptions.hint) {
      var usedImportedElements = <UsedImportedElements>[];
      var usedLocalElements = <UsedLocalElements>[];
      for (var unit in units.values) {
        {
          var visitor = GatherUsedLocalElementsVisitor(_libraryElement);
          unit.accept(visitor);
          usedLocalElements.add(visitor.usedElements);
        }
        {
          var visitor = GatherUsedImportedElementsVisitor(_libraryElement);
          unit.accept(visitor);
          usedImportedElements.add(visitor.usedElements);
        }
      }
      UsedLocalElements usedElements =
          UsedLocalElements.merge(usedLocalElements);
      units.forEach((file, unit) {
        _computeHints(
          file,
          unit,
          usedImportedElements: usedImportedElements,
          usedElements: usedElements,
        );
      });
    }

    if (_analysisOptions.lint) {
      final allUnits = _library.files
          .map((file) {
            final unit = units[file];
            if (unit != null) {
              return LinterContextUnit2(file, unit);
            } else {
              return null;
            }
          })
          .whereNotNull()
          .toList();
      for (final linterUnit in allUnits) {
        _computeLints(linterUnit.file, linterUnit, allUnits,
            analysisOptions: _analysisOptions);
      }
    }

    assert(units.values.every(LegacyTypeAsserter.assertLegacyTypes));

    _checkForInconsistentLanguageVersionOverride(units);

    // This must happen after all other diagnostics have been computed but
    // before the list of diagnostics has been filtered.
    for (var file in _library.files) {
      final ignoreInfo = _fileToIgnoreInfo[file];
      // TODO(scheglov) make it safer
      if (ignoreInfo != null) {
        IgnoreValidator(
          _getErrorReporter(file),
          _getErrorListener(file).errors,
          ignoreInfo,
          _fileToLineInfo[file]!,
          _analysisOptions.unignorableNames,
        ).reportErrors();
      }
    }
  }

  void _computeHints(
    FileState file,
    CompilationUnit unit, {
    required List<UsedImportedElements> usedImportedElements,
    required UsedLocalElements usedElements,
  }) {
    AnalysisErrorListener errorListener = _getErrorListener(file);
    ErrorReporter errorReporter = _getErrorReporter(file);

    if (!_libraryElement.isNonNullableByDefault) {
      unit.accept(
        LegacyDeadCodeVerifier(
          errorReporter,
          typeSystem: _typeSystem,
        ),
      );
    }

    UnicodeTextVerifier(errorReporter).verify(unit, file.content);

    unit.accept(DeadCodeVerifier(errorReporter));

    unit.accept(
      BestPracticesVerifier(
        errorReporter,
        _typeProvider,
        _libraryElement,
        unit,
        file.content,
        declaredVariables: _declaredVariables,
        typeSystem: _typeSystem,
        inheritanceManager: _inheritance,
        analysisOptions: _analysisOptions,
        workspacePackage: _library.file.workspacePackage,
      ),
    );

    unit.accept(OverrideVerifier(
      _inheritance,
      _libraryElement,
      errorReporter,
    ));

    TodoFinder(errorReporter).findIn(unit);
    LanguageVersionOverrideVerifier(errorReporter).verify(unit);

    // Verify imports.
    {
      ImportsVerifier verifier = ImportsVerifier();
      verifier.addImports(unit);
      usedImportedElements.forEach(verifier.removeUsedElements);
      verifier.generateDuplicateImportHints(errorReporter);
      verifier.generateDuplicateShownHiddenNameHints(errorReporter);
      verifier.generateUnusedImportHints(errorReporter);
      verifier.generateUnusedShownNameHints(errorReporter);
      verifier.generateUnnecessaryImportHints(
          errorReporter, usedImportedElements);
    }

    // Unused local elements.
    {
      UnusedLocalElementsVerifier visitor = UnusedLocalElementsVerifier(
          errorListener, usedElements, _inheritance, _libraryElement);
      unit.accept(visitor);
    }

    //
    // Find code that uses features from an SDK version that does not satisfy
    // the SDK constraints specified in analysis options.
    //
    var sdkVersionConstraint = _analysisOptions.sdkVersionConstraint;
    if (sdkVersionConstraint != null) {
      SdkConstraintVerifier verifier = SdkConstraintVerifier(
          errorReporter, _libraryElement, _typeProvider, sdkVersionConstraint);
      unit.accept(verifier);
    }
  }

  void _computeLints(
    FileState file,
    LinterContextUnit currentUnit,
    List<LinterContextUnit> allUnits, {
    required AnalysisOptionsImpl analysisOptions,
  }) {
    var unit = currentUnit.unit;
    var errorReporter = _getErrorReporter(file);

    var enableTiming = analysisOptions.enableTiming;
    var nodeRegistry = NodeLintRegistry(enableTiming);

    var context = LinterContextImpl(
      allUnits,
      currentUnit,
      _declaredVariables,
      _typeProvider,
      _typeSystem,
      _inheritance,
      analysisOptions,
      file.workspacePackage,
    );
    for (var linter in analysisOptions.lintRules) {
      linter.reporter = errorReporter;
      var timer = enableTiming ? lintRegistry.getTimer(linter) : null;
      timer?.start();
      linter.registerNodeProcessors(nodeRegistry, context);
      timer?.stop();
    }

    // Run lints that handle specific node types.
    unit.accept(
      LinterVisitor(
        nodeRegistry,
        LinterExceptionHandler(
          propagateExceptions: analysisOptions.propagateLinterExceptions,
        ).logException,
      ),
    );
  }

  void _computeVerifyErrors(FileState file, CompilationUnit unit) {
    ErrorReporter errorReporter = _getErrorReporter(file);

    if (!unit.featureSet.isEnabled(Feature.non_nullable)) {
      CodeChecker checker = CodeChecker(
        _typeProvider,
        _typeSystem,
        errorReporter,
      );
      checker.visitCompilationUnit(unit);
    }

    //
    // Use the ConstantVerifier to compute errors.
    //
    _computeConstantErrors(errorReporter, unit);

    //
    // Compute inheritance and override errors.
    //
    var inheritanceOverrideVerifier =
        InheritanceOverrideVerifier(_typeSystem, _inheritance, errorReporter);
    inheritanceOverrideVerifier.verifyUnit(unit);

    //
    // Use the ErrorVerifier to compute errors.
    //
    ErrorVerifier errorVerifier = ErrorVerifier(
        errorReporter, _libraryElement, _typeProvider, _inheritance);
    unit.accept(errorVerifier);

    // Verify constraints on FFI uses. The CFE enforces these constraints as
    // compile-time errors and so does the analyzer.
    unit.accept(FfiVerifier(_typeSystem, errorReporter));
  }

  /// Return a subset of the given [errors] that are not marked as ignored in
  /// the [file].
  List<AnalysisError> _filterIgnoredErrors(
      FileState file, List<AnalysisError> errors) {
    if (errors.isEmpty) {
      return errors;
    }

    IgnoreInfo ignoreInfo = _fileToIgnoreInfo[file]!;
    if (!ignoreInfo.hasIgnores) {
      return errors;
    }

    LineInfo lineInfo = _fileToLineInfo[file]!;

    var unignorableCodes = _analysisOptions.unignorableNames;

    bool isIgnored(AnalysisError error) {
      var code = error.errorCode;
      // Don't allow un-ignorable codes to be ignored.
      if (unignorableCodes.contains(code.name) ||
          unignorableCodes.contains(code.uniqueName) ||
          // Lint rules have lower case names.
          unignorableCodes.contains(code.name.toUpperCase())) {
        return false;
      }
      int errorLine = lineInfo.getLocation(error.offset).lineNumber;
      return ignoreInfo.ignoredAt(code, errorLine);
    }

    return errors.where((AnalysisError e) => !isIgnored(e)).toList();
  }

  RecordingErrorListener _getErrorListener(FileState file) =>
      _errorListeners.putIfAbsent(file, () => RecordingErrorListener());

  ErrorReporter _getErrorReporter(FileState file) {
    return _errorReporters.putIfAbsent(file, () {
      RecordingErrorListener listener = _getErrorListener(file);
      return ErrorReporter(
        listener,
        file.source,
        isNonNullableByDefault: _libraryElement.isNonNullableByDefault,
      );
    });
  }

  /// Return a new parsed unresolved [CompilationUnit].
  CompilationUnitImpl _parse(FileState file) {
    AnalysisErrorListener errorListener = _getErrorListener(file);
    String content = file.content;
    var unit = file.parse(errorListener);

    // TODO(scheglov) Store [IgnoreInfo] as unlinked data.
    _fileToLineInfo[file] = unit.lineInfo;
    _fileToIgnoreInfo[file] = IgnoreInfo.forDart(unit, content);

    return unit;
  }

  /// Parse and resolve all files in [_library].
  Map<FileState, CompilationUnitImpl> _parseAndResolve() {
    // Parse all files.
    final libraryFile = _library.file;
    final libraryUnit = _parse(libraryFile);
    final units = <FileState, CompilationUnitImpl>{
      libraryFile: libraryUnit,
    };
    for (final part in _library.parts) {
      if (part is PartDirectiveWithFile) {
        final partFile = part.includedPart?.file;
        if (partFile != null) {
          units[partFile] = _parse(partFile);
        }
      }
    }

    // Resolve URIs in directives to corresponding sources.
    _resolveDirectives(units, libraryUnit);

    units.forEach((file, unit) {
      _resolveFile(file, unit);
    });

    _computeConstants(units.values);

    return units;
  }

  void _resolveDirectives(
    Map<FileState, CompilationUnitImpl> units,
    CompilationUnitImpl libraryUnit,
  ) {
    libraryUnit.element = _libraryElement.definingCompilationUnit;

    ErrorReporter libraryErrorReporter = _getErrorReporter(_library.file);

    var importIndex = 0;
    var exportIndex = 0;

    LibraryIdentifier? libraryNameNode;
    var seenPartSources = <Source>{};
    var directivesToResolve = <DirectiveImpl>[];
    final partIndexes = _PartDirectiveIndexes();
    for (Directive directive in libraryUnit.directives) {
      if (directive is LibraryDirectiveImpl) {
        libraryNameNode = directive.name;
        directivesToResolve.add(directive);
      } else if (directive is AugmentationImportDirective) {
        // TODO(scheglov) implement
        throw UnimplementedError();
      } else if (directive is ImportDirectiveImpl) {
        _resolveImportDirective(
          directive: directive,
          importElement: _libraryElement.imports[importIndex],
          importState: _library.imports[importIndex],
          libraryErrorReporter: libraryErrorReporter,
        );
        importIndex++;
      } else if (directive is ExportDirectiveImpl) {
        _resolveExportDirective(
          directive: directive,
          exportElement: _libraryElement.exports[exportIndex],
          exportState: _library.exports[exportIndex],
          libraryErrorReporter: libraryErrorReporter,
        );
        exportIndex++;
      } else if (directive is PartDirectiveImpl) {
        _resolvePartDirective(
          directive: directive,
          partIndexes: partIndexes,
          libraryErrorReporter: libraryErrorReporter,
          libraryNameNode: libraryNameNode,
          units: units,
          directivesToResolve: directivesToResolve,
          seenPartSources: seenPartSources,
        );
      }
    }

    // TODO(brianwilkerson) Report the error
    // ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART

    //
    // Resolve the relevant directives to the library element.
    //
    for (var directive in directivesToResolve) {
      directive.element = _libraryElement;
    }
  }

  void _resolveExportDirective({
    required ExportDirectiveImpl directive,
    required ExportElement exportElement,
    required ExportDirectiveState exportState,
    required ErrorReporter libraryErrorReporter,
  }) {
    directive.element = exportElement;
    _resolveNamespaceDirective(
      directive: directive,
      primaryUriNode: directive.uri,
      primaryUriState: exportState.uris.primary,
      configurationNodes: directive.configurations,
      configurationUris: exportState.uris.configurations,
      selectedUriState: exportState.selectedUri,
    );
    if (exportState is ExportDirectiveWithUri) {
      final selectedUriStr = exportState.selectedUri.relativeUriStr;
      if (selectedUriStr.startsWith('dart-ext:')) {
        libraryErrorReporter.reportErrorForNode(
          CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
          directive.uri,
        );
      } else if (exportState.exportedSource == null) {
        final errorCode = exportState.selectedUri.isValid
            ? CompileTimeErrorCode.URI_DOES_NOT_EXIST
            : CompileTimeErrorCode.INVALID_URI;
        libraryErrorReporter.reportErrorForNode(
          errorCode,
          directive.uri,
          [selectedUriStr],
        );
      } else if (exportState is ExportDirectiveWithFile &&
          !exportState.exportedFile.exists) {
        final errorCode = isGeneratedSource(exportState.exportedSource)
            ? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
            : CompileTimeErrorCode.URI_DOES_NOT_EXIST;
        libraryErrorReporter.reportErrorForNode(
          errorCode,
          directive.uri,
          [selectedUriStr],
        );
      } else if (exportState.exportedLibrarySource == null) {
        libraryErrorReporter.reportErrorForNode(
          CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
          directive.uri,
          [selectedUriStr],
        );
      }
    } else {
      libraryErrorReporter.reportErrorForNode(
        CompileTimeErrorCode.URI_WITH_INTERPOLATION,
        directive.uri,
      );
    }
  }

  void _resolveFile(FileState file, CompilationUnit unit) {
    var source = file.source;
    RecordingErrorListener errorListener = _getErrorListener(file);

    var unitElement = unit.declaredElement as CompilationUnitElementImpl;

    unit.accept(
      ResolutionVisitor(
        unitElement: unitElement,
        errorListener: errorListener,
        featureSet: unit.featureSet,
        nameScope: _libraryElement.scope,
        elementWalker: ElementWalker.forCompilationUnit(
          unitElement,
          libraryFilePath: _library.file.path,
          unitFilePath: file.path,
        ),
      ),
    );

    unit.accept(ScopeResolverVisitor(
        _libraryElement, source, _typeProvider, errorListener,
        nameScope: _libraryElement.scope));

    // Nothing for RESOLVED_UNIT8?
    // Nothing for RESOLVED_UNIT9?
    // Nothing for RESOLVED_UNIT10?

    FlowAnalysisHelper flowAnalysisHelper =
        FlowAnalysisHelper(_typeSystem, _testingData != null, unit.featureSet);
    _testingData?.recordFlowAnalysisDataForTesting(
        file.uri, flowAnalysisHelper.dataForTesting!);

    unit.accept(ResolverVisitor(
        _inheritance, _libraryElement, source, _typeProvider, errorListener,
        featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper));
  }

  void _resolveImportDirective({
    required ImportDirectiveImpl directive,
    required ImportElement importElement,
    required ImportDirectiveState importState,
    required ErrorReporter libraryErrorReporter,
  }) {
    directive.element = importElement;
    directive.prefix?.staticElement = importElement.prefix;
    _resolveNamespaceDirective(
      directive: directive,
      primaryUriNode: directive.uri,
      primaryUriState: importState.uris.primary,
      configurationNodes: directive.configurations,
      configurationUris: importState.uris.configurations,
      selectedUriState: importState.selectedUri,
    );
    if (importState is ImportDirectiveWithUri) {
      final selectedUriStr = importState.selectedUri.relativeUriStr;
      if (selectedUriStr.startsWith('dart-ext:')) {
        libraryErrorReporter.reportErrorForNode(
          CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
          directive.uri,
        );
      } else if (importState.importedSource == null) {
        final errorCode = importState.selectedUri.isValid
            ? CompileTimeErrorCode.URI_DOES_NOT_EXIST
            : CompileTimeErrorCode.INVALID_URI;
        libraryErrorReporter.reportErrorForNode(
          errorCode,
          directive.uri,
          [selectedUriStr],
        );
      } else if (importState is ImportDirectiveWithFile &&
          !importState.importedFile.exists) {
        final errorCode = isGeneratedSource(importState.importedSource)
            ? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
            : CompileTimeErrorCode.URI_DOES_NOT_EXIST;
        libraryErrorReporter.reportErrorForNode(
          errorCode,
          directive.uri,
          [selectedUriStr],
        );
      } else if (importState.importedLibrarySource == null) {
        libraryErrorReporter.reportErrorForNode(
          CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
          directive.uri,
          [selectedUriStr],
        );
      }
    } else {
      libraryErrorReporter.reportErrorForNode(
        CompileTimeErrorCode.URI_WITH_INTERPOLATION,
        directive.uri,
      );
    }
  }

  void _resolveNamespaceDirective({
    required NamespaceDirectiveImpl directive,
    required StringLiteralImpl primaryUriNode,
    required file_state.DirectiveUri primaryUriState,
    required file_state.DirectiveUri selectedUriState,
    required List<Configuration> configurationNodes,
    required List<file_state.DirectiveUri> configurationUris,
  }) {
    for (var i = 0; i < configurationNodes.length; i++) {
      final configurationNode = configurationNodes[i];
      configurationNode as ConfigurationImpl;
      configurationNode.uriSource = configurationUris[i].source;
    }

    if (primaryUriState is DirectiveUriWithString) {
      directive.uriContent = primaryUriState.relativeUriStr;
      directive.uriSource = primaryUriState.source;
    }

    if (selectedUriState is DirectiveUriWithString) {
      directive.selectedUriContent = selectedUriState.relativeUriStr;
      directive.selectedSource = selectedUriState.source;
    }
  }

  void _resolvePartDirective({
    required PartDirectiveImpl directive,
    required _PartDirectiveIndexes partIndexes,
    required ErrorReporter libraryErrorReporter,
    required LibraryIdentifier? libraryNameNode,
    required Map<FileState, CompilationUnitImpl> units,
    required List<DirectiveImpl> directivesToResolve,
    required Set<Source> seenPartSources,
  }) {
    StringLiteral partUri = directive.uri;

    final index = partIndexes.directive++;

    final partState = _library.parts[index];
    directive.uriSource = partState.includedSource;

    final partElement = _libraryElement.parts2[index];
    directive.element = partElement;

    if (partState is! PartDirectiveWithUri) {
      libraryErrorReporter.reportErrorForNode(
        CompileTimeErrorCode.URI_WITH_INTERPOLATION,
        directive.uri,
      );
      return;
    }

    if (partState is! PartDirectiveWithFile) {
      final errorCode = partState.uri.isValid
          ? CompileTimeErrorCode.URI_DOES_NOT_EXIST
          : CompileTimeErrorCode.INVALID_URI;
      libraryErrorReporter.reportErrorForNode(
        errorCode,
        directive.uri,
        [partState.uri.relativeUriStr],
      );
      return;
    }
    final includedFile = partState.includedFile;
    final includedKind = includedFile.kind;

    if (includedKind is! PartFileStateKind) {
      if (includedFile.exists) {
        libraryErrorReporter.reportErrorForNode(
          CompileTimeErrorCode.PART_OF_NON_PART,
          partUri,
          [partUri.toSource()],
        );
      } else {
        final errorCode = isGeneratedSource(includedFile.source)
            ? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
            : CompileTimeErrorCode.URI_DOES_NOT_EXIST;
        libraryErrorReporter.reportErrorForNode(
          errorCode,
          directive.uri,
          [partUri.toSource()],
        );
      }
      return;
    }

    if (includedKind is PartOfNameFileStateKind) {
      if (!includedKind.libraries.contains(_library)) {
        final name = includedKind.directive.name;
        if (libraryNameNode == null) {
          libraryErrorReporter.reportErrorForNode(
            CompileTimeErrorCode.PART_OF_UNNAMED_LIBRARY,
            partUri,
            [name],
          );
        } else {
          libraryErrorReporter.reportErrorForNode(
            CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
            partUri,
            [libraryNameNode.name, name],
          );
        }
        return;
      }
    } else if (includedKind.library != _library) {
      libraryErrorReporter.reportErrorForNode(
        CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
        partUri,
        [_library.file.uriStr, includedFile.uriStr],
      );
      return;
    }

    var partUnit = units[includedFile]!;
    final partElementUri = partElement.uri;
    if (partElementUri is DirectiveUriWithUnit) {
      partUnit.element = partElementUri.unit;
    }

    final partSource = includedKind.file.source;
    directive.uriSource = partSource;

    for (final directive in partUnit.directives) {
      if (directive is PartOfDirectiveImpl) {
        directivesToResolve.add(directive);
      }
    }

    //
    // Validate that the part source is unique in the library.
    //
    if (!seenPartSources.add(partSource)) {
      libraryErrorReporter.reportErrorForNode(
          CompileTimeErrorCode.DUPLICATE_PART, partUri, [partSource.uri]);
    }
  }

  /// Find constants in [unit] to compute.
  static List<ConstantEvaluationTarget> _findConstants(CompilationUnit unit) {
    ConstantFinder constantFinder = ConstantFinder();
    unit.accept(constantFinder);

    var dependenciesFinder = ConstantExpressionsDependenciesFinder();
    unit.accept(dependenciesFinder);
    return [
      ...constantFinder.constantsToCompute,
      ...dependenciesFinder.dependencies,
    ];
  }

  static bool _hasEmptyCompletionContext(AstNode? node) {
    if (node is DoubleLiteral || node is IntegerLiteral) {
      return true;
    }

    if (node is SimpleIdentifier) {
      var parent = node.parent;

      if (parent is ConstructorDeclaration && parent.name == node) {
        return true;
      }

      if (parent is ConstructorFieldInitializer && parent.fieldName == node) {
        return true;
      }

      if (parent is FormalParameter && parent.identifier == node) {
        // We use elements to access fields.
        if (parent is FieldFormalParameter) {
          return false;
        }
        // We use elements to access the enclosing constructor.
        if (parent is SuperFormalParameter) {
          return false;
        }
        // We have a contributor that looks at the type, but it is syntactic.
        return true;
      }

      if (parent is FunctionDeclaration && parent.name == node) {
        return true;
      }

      if (parent is MethodDeclaration && parent.name == node) {
        return true;
      }

      // The name of a NamedType does not provide any context.
      // So, we don't need to resolve anything.
      if (parent is NamedType) {
        var parent3 = parent.parent?.parent;
        // `class A {foo^ int bar = 0;}` looks as `class A {foo int; bar = 0;}`.
        if (parent3 is FieldDeclaration) {
          return false;
        }
        // `{foo^ print(0);}` looks as `foo print; (0);`.
        if (parent3 is VariableDeclarationStatement &&
            parent3.semicolon.isSynthetic) {
          return false;
        }
        return true;
      }

      if (parent is TypeParameter && parent.name == node) {
        return true;
      }

      // We have a contributor that looks at the type, but it is syntactic.
      if (parent is VariableDeclaration && parent.name == node) {
        final parent2 = parent.parent;
        final parent3 = parent2?.parent;
        // `class A { foo^ }` looks like `class A { <noType> foo; }`.
        if (parent2 is VariableDeclarationList &&
            parent2.type == null &&
            parent3 is FieldDeclaration &&
            parent3.semicolon.isSynthetic) {
          return false;
        }
        return true;
      }
    }

    return false;
  }
}

/// Analysis result for single file.
class UnitAnalysisResult {
  final FileState file;
  final CompilationUnit unit;
  final List<AnalysisError> errors;

  UnitAnalysisResult(this.file, this.unit, this.errors);
}

class _PartDirectiveIndexes {
  int directive = 0;
  int element = 0;
}
