Keep more specific types for AnalysisContextCollectionImpl to avoid downcasts.

It seems to me that implicitly expecting DriverBasedAnalysisContext
is equivalent to explicitly stating this with types.

Change-Id: I16ec14e73030d9b34242a2f4ad582e93fc44afa7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/189382
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 6fd6cb7..ec9494ef 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -399,13 +399,12 @@
       sdkPath: sdkManager.defaultSdkDirectory,
     );
 
-    for (var context in _collection.contexts) {
-      var contextImpl = context as DriverBasedAnalysisContext;
-      var driver = contextImpl.driver;
+    for (var analysisContext in _collection.contexts) {
+      var driver = analysisContext.driver;
 
       callbacks.listenAnalysisDriver(driver);
 
-      var rootFolder = contextImpl.contextRoot.root;
+      var rootFolder = analysisContext.contextRoot.root;
       driverMap[rootFolder] = driver;
 
       changeSubscriptions[rootFolder] = rootFolder.changes
@@ -413,7 +412,7 @@
 
       _watchBazelFilesIfNeeded(rootFolder, driver);
 
-      for (var file in contextImpl.contextRoot.analyzedFiles()) {
+      for (var file in analysisContext.contextRoot.analyzedFiles()) {
         if (file_paths.isAndroidManifestXml(pathContext, file)) {
           _analyzeAndroidManifestXml(driver, file);
         } else if (file_paths.isDart(pathContext, file)) {
@@ -421,7 +420,7 @@
         }
       }
 
-      var optionsFile = context.contextRoot.optionsFile;
+      var optionsFile = analysisContext.contextRoot.optionsFile;
       if (optionsFile != null) {
         _analyzeAnalysisOptionsYaml(driver, optionsFile.path);
       }
@@ -455,8 +454,7 @@
   void _destroyAnalysisContexts() {
     if (_collection != null) {
       for (var analysisContext in _collection.contexts) {
-        var contextImpl = analysisContext as DriverBasedAnalysisContext;
-        _destroyAnalysisContext(contextImpl);
+        _destroyAnalysisContext(analysisContext);
       }
       callbacks.afterContextsDestroyed();
     }
@@ -530,8 +528,7 @@
     }
 
     if (file_paths.isDart(pathContext, path)) {
-      for (var analysisContext_ in _collection.contexts) {
-        var analysisContext = analysisContext_ as DriverBasedAnalysisContext;
+      for (var analysisContext in _collection.contexts) {
         switch (type) {
           case ChangeType.ADD:
             if (analysisContext.contextRoot.isAnalyzed(path)) {
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index a9baa35..3598a1f 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/analysis_context.dart';
-import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -48,17 +47,11 @@
   final ByteStore _byteStore = MemoryByteStore();
 
   final Map<String, String> _declaredVariables = {};
-  AnalysisContextCollection _analysisContextCollection;
-
-  List<AnalysisContext> get allContexts {
-    _createAnalysisContexts();
-    return _analysisContextCollection.contexts;
-  }
+  AnalysisContextCollectionImpl _analysisContextCollection;
 
   List<AnalysisDriver> get allDrivers {
-    return allContexts
-        .map((e) => (e as DriverBasedAnalysisContext).driver)
-        .toList();
+    _createAnalysisContexts();
+    return _analysisContextCollection.contexts.map((e) => e.driver).toList();
   }
 
   /// The file system specific `/home/test/analysis_options.yaml` path.
@@ -107,10 +100,7 @@
   }
 
   AnalysisContext contextFor(String path) {
-    _createAnalysisContexts();
-
-    path = convertPath(path);
-    return _analysisContextCollection.contextFor(path);
+    return _contextFor(path);
   }
 
   /// Create an analysis options file based on the given arguments.
@@ -149,8 +139,7 @@
   }
 
   AnalysisDriver driverFor(String path) {
-    var context = contextFor(path) as DriverBasedAnalysisContext;
-    return context.driver;
+    return _contextFor(path).driver;
   }
 
   /// Return the existing analysis context that should be used to analyze the
@@ -263,10 +252,9 @@
 
   void _addAnalyzedFilesToDrivers() {
     for (var analysisContext in _analysisContextCollection.contexts) {
-      var driver = (analysisContext as DriverBasedAnalysisContext).driver;
       for (var path in analysisContext.contextRoot.analyzedFiles()) {
         if (file_paths.isDart(resourceProvider.pathContext, path)) {
-          driver.addFile(path);
+          analysisContext.driver.addFile(path);
         }
       }
     }
@@ -276,13 +264,19 @@
     if (_analysisContextCollection != null) {
       for (var analysisContext in _analysisContextCollection.contexts) {
         if (analysisContext.contextRoot.isAnalyzed(path)) {
-          var driver = (analysisContext as DriverBasedAnalysisContext).driver;
-          driver.addFile(path);
+          analysisContext.driver.addFile(path);
         }
       }
     }
   }
 
+  DriverBasedAnalysisContext _contextFor(String path) {
+    _createAnalysisContexts();
+
+    path = convertPath(path);
+    return _analysisContextCollection.contextFor(path);
+  }
+
   /// Create all analysis contexts in [collectionIncludedPaths].
   void _createAnalysisContexts() {
     if (_analysisContextCollection != null) {
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index a271a87..cd32542 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -19,7 +19,6 @@
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analysis_server/src/status/pages.dart';
-import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -44,8 +43,8 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
@@ -646,7 +645,7 @@
     // line below.
 //    compareIndividualFeatures();
 
-    final collection = AnalysisContextCollection(
+    final collection = AnalysisContextCollectionImpl(
       includedPaths: [rootPath],
       resourceProvider: PhysicalResourceProvider.INSTANCE,
     );
@@ -1109,7 +1108,7 @@
   /// should be captured in the [collector].
   Future<void> _computeInContext(ContextRoot root) async {
     // Create a new collection to avoid consuming large quantities of memory.
-    final collection = AnalysisContextCollection(
+    final collection = AnalysisContextCollectionImpl(
       includedPaths: root.includedPaths.toList(),
       excludedPaths: root.excludedPaths.toList(),
       resourceProvider: _provider,
@@ -1174,9 +1173,7 @@
               _provider.setOverlay(filePath,
                   content: overlayContents,
                   modificationStamp: overlayModificationStamp++);
-              (context as DriverBasedAnalysisContext)
-                  .driver
-                  .changeFile(filePath);
+              context.driver.changeFile(filePath);
               resolvedUnitResult =
                   await context.currentSession.getResolvedUnit(filePath);
             }
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index 4de4a89..dbe5024 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
@@ -2,7 +2,6 @@
 // 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/analysis_context.dart';
 import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/context_locator.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -11,6 +10,7 @@
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/context_builder.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
@@ -23,7 +23,7 @@
 
   /// The list of analysis contexts.
   @override
-  final List<AnalysisContext> contexts = [];
+  final List<DriverBasedAnalysisContext> contexts = [];
 
   /// Initialize a newly created analysis context manager.
   AnalysisContextCollectionImpl({
@@ -80,7 +80,7 @@
   }
 
   @override
-  AnalysisContext contextFor(String path) {
+  DriverBasedAnalysisContext contextFor(String path) {
     _throwIfNotAbsoluteNormalizedPath(path);
 
     for (var context in contexts) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index ffead36..531689b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -2,7 +2,6 @@
 // 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/analysis_context.dart';
 import 'package:analyzer/dart/analysis/context_builder.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -38,7 +37,7 @@
             resourceProvider ?? PhysicalResourceProvider.INSTANCE;
 
   @override
-  AnalysisContext createContext({
+  DriverBasedAnalysisContext createContext({
     ByteStore? byteStore,
     required ContextRoot contextRoot,
     DeclaredVariables? declaredVariables,
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index 776814b..af27464 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/src/dart/analysis/context_builder.dart';
 import 'package:analyzer/src/dart/analysis/context_root.dart';
-import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/workspace/basic.dart';
@@ -49,7 +48,7 @@
       contextRoot: contextRoot,
       declaredVariables: declaredVariables,
       sdkPath: resourceProvider.convertPath(sdkRoot),
-    ) as DriverBasedAnalysisContext;
+    );
     expect(context.analysisOptions, isNotNull);
     expect(context.contextRoot, contextRoot);
     assertEquals(context.driver.declaredVariables, declaredVariables);
@@ -60,10 +59,10 @@
         DeclaredVariables.fromMap({'bar': 'true'});
     MockSdk sdk = MockSdk(resourceProvider: resourceProvider);
     var context = contextBuilder.createContext(
-            contextRoot: contextRoot,
-            declaredVariables: declaredVariables,
-            sdkPath: resourceProvider.convertPath(sdkRoot))
-        as DriverBasedAnalysisContext;
+      contextRoot: contextRoot,
+      declaredVariables: declaredVariables,
+      sdkPath: resourceProvider.convertPath(sdkRoot),
+    );
     expect(context.analysisOptions, isNotNull);
     expect(context.contextRoot, contextRoot);
     assertEquals(context.driver.declaredVariables, declaredVariables);
@@ -84,9 +83,9 @@
   test_createContext_sdkPath() {
     MockSdk sdk = MockSdk(resourceProvider: resourceProvider);
     var context = contextBuilder.createContext(
-            contextRoot: contextRoot,
-            sdkPath: resourceProvider.convertPath(sdkRoot))
-        as DriverBasedAnalysisContext;
+      contextRoot: contextRoot,
+      sdkPath: resourceProvider.convertPath(sdkRoot),
+    );
     expect(context.analysisOptions, isNotNull);
     expect(context.contextRoot, contextRoot);
     expect(context.driver.sourceFactory.dartSdk!.mapDartUri('dart:core'),
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 3582753..84d9950 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -111,7 +111,7 @@
   ByteStore _byteStore = getContextResolutionTestByteStore();
 
   Map<String, String> _declaredVariables = {};
-  AnalysisContextCollection? _analysisContextCollection;
+  AnalysisContextCollectionImpl? _analysisContextCollection;
 
   /// If not `null`, [resolveFile] will use the context that corresponds
   /// to this path, instead of the given path.
@@ -157,10 +157,7 @@
   }
 
   AnalysisContext contextFor(String path) {
-    _createAnalysisContexts();
-
-    path = convertPath(path);
-    return _analysisContextCollection!.contextFor(path);
+    return _contextFor(path);
   }
 
   void disposeAnalysisContextCollection() {
@@ -170,8 +167,7 @@
   }
 
   AnalysisDriver driverFor(String path) {
-    var context = contextFor(path) as DriverBasedAnalysisContext;
-    return context.driver;
+    return _contextFor(path).driver;
   }
 
   @override
@@ -211,6 +207,13 @@
 
   void verifyCreatedCollection() {}
 
+  DriverBasedAnalysisContext _contextFor(String path) {
+    _createAnalysisContexts();
+
+    path = convertPath(path);
+    return _analysisContextCollection!.contextFor(path);
+  }
+
   /// Create all analysis contexts in [collectionIncludedPaths].
   void _createAnalysisContexts() {
     if (_analysisContextCollection != null) {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index dde233c..2767510 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -596,8 +596,7 @@
   }
 
   void _setContextForPath(String path) {
-    var analysisContext = _collection.contextFor(path);
-    _analysisContext = analysisContext as DriverBasedAnalysisContext;
+    _analysisContext = _collection.contextFor(path);
   }
 
   void _updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index f95ad22..7a0c3d4 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart' as analyzer;
 import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:test/test.dart';
@@ -670,22 +669,9 @@
   }
 
   Future<void> test_MapLiteral_expression() async {
-    super.setUp();
-    final experimentStatus = (driverFor(testPackageRootPath).analysisOptions
-            as analyzer.AnalysisOptionsImpl)
-        .experimentStatus;
-    if (experimentStatus.control_flow_collections ||
-        experimentStatus.spread_collections) {
-      // SimpleIdentifier  MapLiteral  VariableDeclaration
-      await createTarget('foo = {1: 2, T^');
-      assertTarget('T', '{1 : 2, T}');
-    } else {
-      // TODO(b/35569): remove this branch of test behavior
-
-      // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-      await createTarget('foo = {1: 2, T^');
-      assertTarget('T : ', '{1 : 2, T : }');
-    }
+    // SimpleIdentifier  MapLiteral  VariableDeclaration
+    await createTarget('foo = {1: 2, T^');
+    assertTarget('T', '{1 : 2, T}');
   }
 
   Future<void> test_MapLiteralEntry() async {
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index e98a83e..d9f4ca7 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -11,8 +11,6 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/test_utilities/mock_packages.dart';
@@ -89,11 +87,6 @@
     newFile(testPackageAnalysisOptionsPath, content: buffer.toString());
   }
 
-  AnalysisDriver driverFor(String path) {
-    var context = contextFor(path) as DriverBasedAnalysisContext;
-    return context.driver;
-  }
-
   @override
   File newFile(String path, {String content = ''}) {
     if (_analysisContextCollection != null && !path.endsWith('.dart')) {
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index a727c1c..5705e9a 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -5,7 +5,6 @@
 import 'dart:async';
 import 'dart:io' hide File;
 
-import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/diagnostic/diagnostic.dart';
@@ -511,7 +510,7 @@
 
   _FixCodeProcessor _fixCodeProcessor;
 
-  AnalysisContextCollection _contextCollection;
+  AnalysisContextCollectionImpl _contextCollection;
 
   bool _hasExceptions = false;
 
@@ -531,16 +530,15 @@
     // Handle the case of more than one analysis context being found (typically,
     // the current directory and one or more sub-directories).
     if (hasMultipleAnalysisContext) {
-      return contextCollection.contextFor(options.directory)
-          as DriverBasedAnalysisContext;
+      return contextCollection.contextFor(options.directory);
     } else {
-      return contextCollection.contexts.single as DriverBasedAnalysisContext;
+      return contextCollection.contexts.single;
     }
   }
 
   Ansi get ansi => logger.ansi;
 
-  AnalysisContextCollection get contextCollection {
+  AnalysisContextCollectionImpl get contextCollection {
     _contextCollection ??= AnalysisContextCollectionImpl(
         includedPaths: [options.directory],
         resourceProvider: resourceProvider,
diff --git a/pkg/nnbd_migration/test/abstract_context.dart b/pkg/nnbd_migration/test/abstract_context.dart
index a52c469..b5d1783 100644
--- a/pkg/nnbd_migration/test/abstract_context.dart
+++ b/pkg/nnbd_migration/test/abstract_context.dart
@@ -5,7 +5,6 @@
 import 'dart:convert';
 
 import 'package:analyzer/dart/analysis/analysis_context.dart';
-import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/overlay_file_system.dart';
@@ -22,7 +21,7 @@
 class AbstractContextTest with ResourceProviderMixin {
   OverlayResourceProvider overlayResourceProvider;
 
-  AnalysisContextCollection _analysisContextCollection;
+  AnalysisContextCollectionImpl _analysisContextCollection;
   AnalysisDriver _driver;
 
   final Set<String> knownPackages = {};
@@ -109,20 +108,14 @@
   /// given [path], or throw [StateError] if the [path] is not analyzed in any
   /// of the created analysis contexts.
   AnalysisContext getContext(String path) {
-    if (_analysisContextCollection == null) {
-      _createAnalysisContexts();
-    }
-    path = convertPath(path);
-    return _analysisContextCollection.contextFor(path);
+    return _getContext(path);
   }
 
   /// Return the existing analysis driver that should be used to analyze the
   /// given [path], or throw [StateError] if the [path] is not analyzed in any
   /// of the created analysis contexts.
   AnalysisDriver getDriver(String path) {
-    DriverBasedAnalysisContext context =
-        getContext(path) as DriverBasedAnalysisContext;
-    return context.driver;
+    return _getContext(path).driver;
   }
 
   LineInfo getLineInfo(String path) => session.getFile(path).lineInfo;
@@ -189,4 +182,15 @@
 
     _driver = getDriver(convertPath(testsPath));
   }
+
+  /// Return the existing analysis context that should be used to analyze the
+  /// given [path], or throw [StateError] if the [path] is not analyzed in any
+  /// of the created analysis contexts.
+  DriverBasedAnalysisContext _getContext(String path) {
+    if (_analysisContextCollection == null) {
+      _createAnalysisContexts();
+    }
+    path = convertPath(path);
+    return _analysisContextCollection.contextFor(path);
+  }
 }