Version 2.15.0-187.0.dev

Merge commit '1d28bf98daf08176d6347c7f18317edd6a0956f2' into 'dev'
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
index 8591b99..225a9fa 100644
--- a/pkg/analysis_server/lib/src/cider/completion.dart
+++ b/pkg/analysis_server/lib/src/cider/completion.dart
@@ -144,10 +144,6 @@
       var result = CiderCompletionResult._(
         suggestions: suggestions,
         performance: CiderCompletionPerformance._(
-          file: Duration.zero,
-          imports: performance.getChild('imports')!.elapsed,
-          resolution: performance.getChild('resolution')!.elapsed,
-          suggestions: performance.getChild('suggestions')!.elapsed,
           operations: _performanceRoot.children.first,
         ),
         prefixStart: CiderPosition(line, column - filter._pattern.length),
@@ -157,15 +153,6 @@
     });
   }
 
-  @Deprecated('Use compute')
-  Future<CiderCompletionResult> compute2({
-    required String path,
-    required int line,
-    required int column,
-  }) async {
-    return compute(path: path, line: line, column: column);
-  }
-
   /// Prepare for computing completions in files from the [pathList].
   ///
   /// This method might be called when we are finishing a large initial
@@ -240,30 +227,10 @@
 }
 
 class CiderCompletionPerformance {
-  /// The elapsed time for file access.
-  @Deprecated('This operation is not performed anymore')
-  final Duration file;
-
-  /// The elapsed time to compute import suggestions.
-  @Deprecated("Use 'operations' instead")
-  final Duration imports;
-
-  /// The elapsed time for resolution.
-  @Deprecated("Use 'operations' instead")
-  final Duration resolution;
-
-  /// The elapsed time to compute suggestions.
-  @Deprecated("Use 'operations' instead")
-  final Duration suggestions;
-
   /// The tree of operation performances.
   final OperationPerformance operations;
 
   CiderCompletionPerformance._({
-    required this.file,
-    required this.imports,
-    required this.resolution,
-    required this.suggestions,
     required this.operations,
   });
 }
diff --git a/pkg/analysis_server/test/src/cider/cider_service.dart b/pkg/analysis_server/test/src/cider/cider_service.dart
index 92b637e..b4d2492 100644
--- a/pkg/analysis_server/test/src/cider/cider_service.dart
+++ b/pkg/analysis_server/test/src/cider/cider_service.dart
@@ -4,7 +4,6 @@
 
 import 'dart:convert';
 
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -14,8 +13,6 @@
 import 'package:linter/src/rules.dart';
 
 class CiderServiceTest with ResourceProviderMixin {
-  final ByteStore byteStore = MemoryByteStore();
-
   final StringBuffer logBuffer = StringBuffer();
   late PerformanceLog logger;
   late MockSdk sdk;
@@ -25,8 +22,6 @@
   String testPath = '/workspace/dart/test/lib/test.dart';
 
   /// Create a new [FileResolver] into [fileResolver].
-  ///
-  /// We do this the first time, and to test reusing results from [byteStore].
   void createFileResolver() {
     var workspace = BazelWorkspace.find(
       resourceProvider,
@@ -36,7 +31,6 @@
     fileResolver = FileResolver(
       logger,
       resourceProvider,
-      byteStore,
       workspace.createSourceFactory(sdk, null),
       (String path) => _getDigest(path),
       null,
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 328c16a..faf698f 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -19,7 +19,6 @@
 import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -603,8 +602,6 @@
     this._byteStore,
     this._sourceFactory,
     this._workspace,
-    @Deprecated('No longer used; will be removed')
-        AnalysisOptions analysisOptions,
     this._linkedSalt,
     this.featureSetProvider,
     this.getFileDigest,
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 21dc0ef..e28b029 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
 import 'package:analyzer/src/context/packages.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' show ErrorEncoding;
 import 'package:analyzer/src/dart/analysis/experiments.dart';
@@ -116,13 +115,11 @@
   FileResolver(
     PerformanceLog logger,
     ResourceProvider resourceProvider,
-    @deprecated ByteStore byteStore,
     SourceFactory sourceFactory,
     String Function(String path) getFileDigest,
     void Function(List<String> paths)? prefetchFiles, {
     required Workspace workspace,
     bool Function(String path)? isGenerated,
-    @deprecated Duration? libraryContextResetTimeout,
   }) : this.from(
           logger: logger,
           resourceProvider: resourceProvider,
@@ -131,9 +128,6 @@
           prefetchFiles: prefetchFiles,
           workspace: workspace,
           isGenerated: isGenerated,
-
-          // ignore: deprecated_member_use_from_same_package
-          libraryContextResetTimeout: libraryContextResetTimeout,
         );
 
   FileResolver.from({
@@ -145,7 +139,6 @@
     required Workspace workspace,
     bool Function(String path)? isGenerated,
     CiderByteStore? byteStore,
-    @deprecated Duration? libraryContextResetTimeout,
   })  : logger = logger,
         sourceFactory = sourceFactory,
         resourceProvider = resourceProvider,
@@ -192,9 +185,6 @@
     removedCacheIds.addAll(libraryContext!.collectSharedDataIdentifiers());
   }
 
-  @deprecated
-  void dispose() {}
-
   /// Looks for references to the Element at the given offset and path. All the
   /// files currently cached by the resolver are searched, generated files are
   /// ignored.
@@ -275,17 +265,6 @@
     });
   }
 
-  @deprecated
-  ErrorsResult getErrors2({
-    required String path,
-    OperationPerformanceImpl? performance,
-  }) {
-    return getErrors(
-      path: path,
-      performance: performance,
-    );
-  }
-
   FileContext getFileContext({
     required String path,
     required OperationPerformanceImpl performance,
@@ -621,9 +600,7 @@
         byteStore,
         sourceFactory,
         workspace,
-        analysisOptions,
-        Uint32List(0),
-        // linkedSalt
+        Uint32List(0), // linkedSalt
         featureSetProvider,
         getFileDigest,
         prefetchFiles,
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 77800d4..908fc31 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -40,22 +40,22 @@
     return false;
   }
   const auto& other_closure = Closure::Cast(other);
-  // Closures that are not implicit closures (tear-offs) are unique.
   const auto& func_a = Function::Handle(zone, receiver.function());
-  if (!func_a.IsImplicitClosureFunction()) {
-    return false;
-  }
   const auto& func_b = Function::Handle(zone, other_closure.function());
-  if (!func_b.IsImplicitClosureFunction()) {
-    return false;
-  }
-  // If the closure functions are not the same, check the function's name and
-  // owner, as multiple function objects could exist for the same function due
-  // to hot reload.
-  if (func_a.ptr() != func_b.ptr() &&
-      (func_a.name() != func_b.name() || func_a.Owner() != func_b.Owner() ||
-       func_a.is_static() != func_b.is_static())) {
-    return false;
+  // Check that functions match.
+  if (func_a.ptr() != func_b.ptr()) {
+    // Closure functions that are not implicit closures (tear-offs) are unique.
+    if (!func_a.IsImplicitClosureFunction() ||
+        !func_b.IsImplicitClosureFunction()) {
+      return false;
+    }
+    // If the closure functions are not the same, check the function's name and
+    // owner, as multiple function objects could exist for the same function due
+    // to hot reload.
+    if ((func_a.name() != func_b.name() || func_a.Owner() != func_b.Owner() ||
+         func_a.is_static() != func_b.is_static())) {
+      return false;
+    }
   }
   // Check that the delayed type argument vectors match.
   if (receiver.delayed_type_arguments() !=
@@ -72,11 +72,25 @@
       return false;
     }
   }
-  if (!func_a.is_static()) {
-    // Check that the both receiver instances are the same.
-    const Context& context_a = Context::Handle(zone, receiver.context());
-    const Context& context_b = Context::Handle(zone, other_closure.context());
-    return context_a.At(0) == context_b.At(0);
+  if (func_a.IsImplicitClosureFunction() &&
+      func_b.IsImplicitClosureFunction()) {
+    if (!func_a.is_static()) {
+      // Check that the both receiver instances are the same.
+      const Context& context_a = Context::Handle(zone, receiver.context());
+      const Context& context_b = Context::Handle(zone, other_closure.context());
+      return context_a.At(0) == context_b.At(0);
+    }
+  } else {
+    // Non-identical closures which are not tear-offs can be equal only if
+    // they are different instantiations of the same generic closure.
+    if (!func_a.IsGeneric() || receiver.IsGeneric() ||
+        (receiver.context() != other_closure.context()) ||
+        (receiver.instantiator_type_arguments() !=
+         other_closure.instantiator_type_arguments()) ||
+        (receiver.function_type_arguments() !=
+         other_closure.function_type_arguments())) {
+      return false;
+    }
   }
   return true;
 }
diff --git a/tools/VERSION b/tools/VERSION
index aa707b0..051c4b1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 186
+PRERELEASE 187
 PRERELEASE_PATCH 0
\ No newline at end of file