Version 2.17.0-40.0.dev

Merge commit '8781ab0151888a4b9eef50f0777d0a0908166d05' into 'dev'
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index e8838ce..3c7bbac 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -155,7 +155,7 @@
     case DeclarationKind.FUNCTION:
       return protocol.ElementKind.FUNCTION;
     case DeclarationKind.FUNCTION_TYPE_ALIAS:
-      return protocol.ElementKind.FUNCTION_TYPE_ALIAS;
+      return protocol.ElementKind.TYPE_ALIAS;
     case DeclarationKind.GETTER:
       return protocol.ElementKind.GETTER;
     case DeclarationKind.METHOD:
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 1dd0f73..490b25f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -14,18 +14,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart'
-    show
-        ClassElement,
-        ConstructorElement,
-        Element,
-        ElementKind,
-        FieldElement,
-        FunctionElement,
-        LibraryElement,
-        LocalVariableElement,
-        PropertyAccessorElement,
-        TopLevelVariableElement;
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/dart/element/type_system.dart';
@@ -60,6 +49,7 @@
     double hasDeprecated = 0.0,
     double isConstant = 0.0,
     double isNoSuchMethod = 0.0,
+    double isNotImported = 0.0,
     double keyword = 0.0,
     double startsWithDollar = 0.0,
     double superMatches = 0.0}) {
@@ -68,6 +58,7 @@
   assert(hasDeprecated.between(-1.0, 0.0));
   assert(isConstant.between(0.0, 1.0));
   assert(isNoSuchMethod.between(-1.0, 0.0));
+  assert(isNotImported.between(-1.0, 0.0));
   assert(keyword.between(0.0, 1.0));
   assert(startsWithDollar.between(-1.0, 0.0));
   assert(superMatches.between(0.0, 1.0));
@@ -77,6 +68,7 @@
     hasDeprecated,
     isConstant,
     isNoSuchMethod,
+    isNotImported,
     keyword,
     startsWithDollar,
     superMatches,
@@ -147,6 +139,7 @@
     0.50, // hasDeprecated
     1.00, // isConstant
     1.00, // isNoSuchMethod
+    1.00, // isNotImported
     1.00, // keyword
     0.50, // startsWithDollar
     1.00, // superMatches
@@ -328,6 +321,25 @@
         : 0.0;
   }
 
+  /// Return the feature for the not-yet-imported property.
+  double isNotImportedFeature(bool isNotImported, Element element) {
+    if (isNotImported) {
+      var enclosing = element.enclosingElement;
+      // The most often case is that we suggest a class.
+      if (enclosing is CompilationUnitElement) {
+        return -1.0;
+      }
+      // But we could also suggest an extension method.
+      if (enclosing is ExtensionElement) {
+        if (!element.isStaticExtensionMember) {
+          return -1.0;
+        }
+      }
+    }
+    // The library is imported, or an unexpected element.
+    return 0.0;
+  }
+
   /// Return the value of the _keyword_ feature for the [keyword] when
   /// completing at the given [completionLocation].
   double keywordFeature(String keyword, String? completionLocation) {
@@ -1047,3 +1059,11 @@
     return null;
   }
 }
+
+extension on Element {
+  bool get isStaticExtensionMember {
+    final self = this;
+    return self is PropertyAccessorElement && self.isStatic ||
+        self is MethodElement && self.isStatic;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
index 50197a2..d814bb5 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/not_imported_contributor.dart
@@ -17,6 +17,11 @@
   final CompletionBudget budget;
   final NotImportedSuggestions additionalData;
 
+  /// When a library is imported with combinators, we cannot skip it, there
+  /// might be elements that were excluded, but should be suggested. So, here
+  /// we record elements that are already imported.
+  final Set<Element> _importedElements = Set.identity();
+
   NotImportedContributor(
     DartCompletionRequest request,
     SuggestionBuilder builder,
@@ -40,6 +45,20 @@
       return;
     }
 
+    var importedLibraries = Set<LibraryElement>.identity();
+    for (var import in request.libraryElement.imports) {
+      var importedLibrary = import.importedLibrary;
+      if (importedLibrary != null) {
+        if (import.combinators.isEmpty) {
+          importedLibraries.add(importedLibrary);
+        } else {
+          _importedElements.addAll(
+            import.namespace.definedNames.values,
+          );
+        }
+      }
+    }
+
     // Use single instance to track getter / setter pairs.
     var extensionContributor = ExtensionMemberContributor(request, builder);
 
@@ -55,13 +74,14 @@
       }
 
       var element = analysisDriver.getLibraryByFile(file);
-      if (element == null) {
+      if (element == null || importedLibraries.contains(element)) {
         continue;
       }
 
       var exportNamespace = element.exportNamespace;
       var exportElements = exportNamespace.definedNames.values.toList();
 
+      builder.isNotImportedLibrary = true;
       builder.laterReplacesEarlier = false;
       builder.suggestionAdded = (suggestion) {
         additionalData.set.add(suggestion);
@@ -74,16 +94,19 @@
       extensionContributor.addExtensions(
         exportElements.whereType<ExtensionElement>().toList(),
       );
-    }
 
-    builder.laterReplacesEarlier = true;
-    builder.suggestionAdded = null;
+      builder.isNotImportedLibrary = false;
+      builder.laterReplacesEarlier = true;
+      builder.suggestionAdded = null;
+    }
   }
 
   void _buildSuggestions(List<Element> elements) {
     var visitor = LibraryElementSuggestionBuilder(request, builder);
     for (var element in elements) {
-      element.accept(visitor);
+      if (!_importedElements.contains(element)) {
+        element.accept(visitor);
+      }
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 3ec8bec..56f5717 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -181,6 +181,10 @@
   final Map<String, CompletionSuggestion> _suggestionMap =
       <String, CompletionSuggestion>{};
 
+  /// This flag is set to `true` while adding suggestions for top-level
+  /// elements from not-yet-imported libraries.
+  bool isNotImportedLibrary = false;
+
   /// A flag indicating whether a suggestion should replace any earlier
   /// suggestions for the same completion (`true`) or whether earlier
   /// suggestions should take priority over more recent suggestions.
@@ -269,6 +273,8 @@
         elementKind: elementKind,
         hasDeprecated: hasDeprecated,
         isConstant: isConstant,
+        isNotImported: request.featureComputer
+            .isNotImportedFeature(isNotImportedLibrary, accessor),
         startsWithDollar: startsWithDollar,
         superMatches: superMatches,
         inheritanceDistance: inheritanceDistance,
@@ -662,6 +668,8 @@
       hasDeprecated: hasDeprecated,
       isConstant: isConstant,
       isNoSuchMethod: isNoSuchMethod,
+      isNotImported: request.featureComputer
+          .isNotImportedFeature(isNotImportedLibrary, method),
       startsWithDollar: startsWithDollar,
       superMatches: superMatches,
       inheritanceDistance: inheritanceDistance,
@@ -938,6 +946,8 @@
         elementKind: elementKind,
         hasDeprecated: hasDeprecated,
         isConstant: isConstant,
+        isNotImported: request.featureComputer
+            .isNotImportedFeature(isNotImportedLibrary, accessor),
         startsWithDollar: startsWithDollar,
         superMatches: superMatches,
       );
@@ -1049,6 +1059,7 @@
       double hasDeprecated = 0.0,
       double isConstant = 0.0,
       double isNoSuchMethod = 0.0,
+      double isNotImported = 0.0,
       double keyword = 0.0,
       double startsWithDollar = 0.0,
       double superMatches = 0.0,
@@ -1061,6 +1072,7 @@
         hasDeprecated: hasDeprecated,
         isConstant: isConstant,
         isNoSuchMethod: isNoSuchMethod,
+        isNotImported: isNotImported,
         keyword: keyword,
         startsWithDollar: startsWithDollar,
         superMatches: superMatches);
@@ -1071,6 +1083,7 @@
       hasDeprecated: hasDeprecated,
       isConstant: isConstant,
       isNoSuchMethod: isNoSuchMethod,
+      isNotImported: isNotImported,
       keyword: keyword,
       startsWithDollar: startsWithDollar,
       superMatches: superMatches,
@@ -1101,6 +1114,8 @@
       elementKind: elementKind,
       hasDeprecated: hasDeprecated,
       isConstant: isConstant,
+      isNotImported: request.featureComputer
+          .isNotImportedFeature(isNotImportedLibrary, element),
     );
   }
 
@@ -1296,6 +1311,7 @@
       double hasDeprecated,
       double isConstant,
       double isNoSuchMethod,
+      double isNotImported,
       double keyword,
       double startsWithDollar,
       double superMatches,
diff --git a/pkg/analysis_server/test/client/completion_driver_test.dart b/pkg/analysis_server/test/client/completion_driver_test.dart
index 50a6021..732e5bb 100644
--- a/pkg/analysis_server/test/client/completion_driver_test.dart
+++ b/pkg/analysis_server/test/client/completion_driver_test.dart
@@ -132,7 +132,9 @@
     );
     await driver.createProject(packageRoots: packageRoots);
 
-    newPubspecYamlFile(projectPath, '');
+    newPubspecYamlFile(projectPath, '''
+name: project
+''');
     newDotPackagesFile(projectPath, content: '''
 project:${toUri('$projectPath/lib')}
 ''');
@@ -279,9 +281,9 @@
 }
 ''');
     assertSuggestion(
-        completion: 'E.e',
-        element: ElementKind.ENUM_CONSTANT,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'E.e',
+      element: ElementKind.ENUM_CONSTANT,
+    );
   }
 
   /// See: https://github.com/dart-lang/sdk/issues/40620
@@ -327,9 +329,9 @@
 ''');
 
     assertSuggestion(
-        completion: 'A',
-        element: ElementKind.CLASS,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'A',
+      element: ElementKind.CLASS,
+    );
   }
 
   Future<void> test_project_lib() async {
@@ -356,33 +358,33 @@
         element: ElementKind.CONSTRUCTOR,
         kind: CompletionSuggestionKind.INVOCATION);
     assertSuggestion(
-        completion: 'A',
-        element: ElementKind.CLASS,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'A',
+      element: ElementKind.CLASS,
+    );
     assertSuggestion(
-        completion: 'E',
-        element: ElementKind.ENUM,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'E',
+      element: ElementKind.ENUM,
+    );
     assertSuggestion(
-        completion: 'Ex',
-        element: ElementKind.EXTENSION,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'Ex',
+      element: ElementKind.EXTENSION,
+    );
     assertSuggestion(
-        completion: 'M',
-        element: ElementKind.MIXIN,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'M',
+      element: ElementKind.MIXIN,
+    );
     assertSuggestion(
-        completion: 'T',
-        element: ElementKind.FUNCTION_TYPE_ALIAS,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'T',
+      element: ElementKind.TYPE_ALIAS,
+    );
     assertSuggestion(
-        completion: 'T2',
-        element: ElementKind.TYPE_ALIAS,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'T2',
+      element: ElementKind.TYPE_ALIAS,
+    );
     assertSuggestion(
-        completion: 'v',
-        element: ElementKind.TOP_LEVEL_VARIABLE,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'v',
+      element: ElementKind.TOP_LEVEL_VARIABLE,
+    );
   }
 
   Future<void> test_project_lib_fields_class() async {
@@ -415,9 +417,9 @@
 ''');
 
     assertSuggestion(
-        completion: 'A.f',
-        element: ElementKind.FIELD,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'A.f',
+      element: ElementKind.FIELD,
+    );
   }
 
   Future<void> test_project_lib_getters_class() async {
@@ -450,9 +452,9 @@
 ''');
 
     assertSuggestion(
-        completion: 'A.g',
-        element: ElementKind.GETTER,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'A.g',
+      element: ElementKind.GETTER,
+    );
   }
 
   /// See: https://github.com/dart-lang/sdk/issues/40626
@@ -468,9 +470,41 @@
 ''');
 
     assertSuggestion(
-        completion: 'g',
-        element: ElementKind.GETTER,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'g',
+      element: ElementKind.GETTER,
+    );
+  }
+
+  Future<void> test_project_lib_methods_class() async {
+    await addProjectFile('lib/a.dart', r'''
+class A {
+  void foo() => 0;
+}
+''');
+
+    await addTestFile('''
+void f() {
+  ^
+}
+''');
+
+    assertNoSuggestion(completion: 'A.foo');
+  }
+
+  Future<void> test_project_lib_methods_static() async {
+    await addProjectFile('lib/a.dart', r'''
+class A {
+  static void foo() => 0;
+}
+''');
+
+    await addTestFile('''
+void f() {
+  ^
+}
+''');
+
+    assertNoSuggestion(completion: 'A.foo');
   }
 
   @failingTest
@@ -541,9 +575,9 @@
 ''');
 
     assertSuggestion(
-        completion: 's',
-        element: ElementKind.SETTER,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 's',
+      element: ElementKind.SETTER,
+    );
   }
 
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38739')
@@ -596,16 +630,17 @@
 ''');
 
     expect(
+      suggestionWith(
+        completion: 'A',
+        element: ElementKind.CONSTRUCTOR,
+      ).relevance,
+      greaterThan(
         suggestionWith(
-                completion: 'A',
-                element: ElementKind.CONSTRUCTOR,
-                kind: CompletionSuggestionKind.INVOCATION)
-            .relevance,
-        greaterThan(suggestionWith(
-                completion: 'A',
-                element: ElementKind.CLASS,
-                kind: CompletionSuggestionKind.INVOCATION)
-            .relevance));
+          completion: 'A',
+          element: ElementKind.CLASS,
+        ).relevance,
+      ),
+    );
   }
 
   /// See: https://github.com/dart-lang/sdk/issues/35529
@@ -620,13 +655,13 @@
 ''');
 
     assertSuggestion(
-        completion: 'M',
-        element: ElementKind.MIXIN,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'M',
+      element: ElementKind.MIXIN,
+    );
     assertSuggestion(
-        completion: 'A',
-        element: ElementKind.CLASS,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'A',
+      element: ElementKind.CLASS,
+    );
   }
 
   Future<void> test_sdk_lib_future_isNotDuplicated() async {
@@ -682,17 +717,17 @@
 
     // + Classes.
     assertSuggestion(
-        completion: 'HashMap',
-        file: '/sdk/lib/collection/collection.dart',
-        element: ElementKind.CLASS,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'HashMap',
+      file: '/sdk/lib/collection/collection.dart',
+      element: ElementKind.CLASS,
+    );
 
     // + Top level variables.
     assertSuggestion(
-        completion: 'pi',
-        file: '/sdk/lib/math/math.dart',
-        element: ElementKind.TOP_LEVEL_VARIABLE,
-        kind: CompletionSuggestionKind.INVOCATION);
+      completion: 'pi',
+      file: '/sdk/lib/math/math.dart',
+      element: ElementKind.TOP_LEVEL_VARIABLE,
+    );
 
     // (No typedefs, enums, extensions defined in the Mock SDK.)
   }
diff --git a/pkg/analysis_server/test/client/impl/completion_driver.dart b/pkg/analysis_server/test/client/impl/completion_driver.dart
index 09285b7..66720b9 100644
--- a/pkg/analysis_server/test/client/impl/completion_driver.dart
+++ b/pkg/analysis_server/test/client/impl/completion_driver.dart
@@ -130,6 +130,20 @@
     return suggestions;
   }
 
+  Future<List<CompletionSuggestion>> getSuggestions2() async {
+    await waitForTasksFinished();
+
+    var request = CompletionGetSuggestions2Params(
+      testFilePath,
+      completionOffset,
+      1 << 16,
+      timeout: 60 * 1000,
+    ).toRequest('0');
+    var response = await waitResponse(request);
+    var result = CompletionGetSuggestions2Result.fromResponse(response);
+    return result.suggestions;
+  }
+
   @override
   File newFile(String path, String content) =>
       resourceProvider.newFile(resourceProvider.convertPath(path), content);
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index ab3ae47..aa70c28 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -334,6 +334,256 @@
       ..suggestions.withElementClass.isEmpty;
   }
 
+  Future<void> test_notImported_lowerRelevance_extension_getter() async {
+    await _configureWithWorkspaceRoot();
+
+    newFile('$testPackageLibPath/a.dart', content: '''
+extension E1 on int {
+  int get foo01 => 0;
+}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+extension E2 on int {
+  int get foo02 => 0;
+}
+''');
+
+    var response = await _getTestCodeSuggestions(r'''
+import 'b.dart';
+ 
+void f() {
+  0.foo0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // `foo01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
+  Future<void> test_notImported_lowerRelevance_extension_method() async {
+    await _configureWithWorkspaceRoot();
+
+    newFile('$testPackageLibPath/a.dart', content: '''
+extension E1 on int {
+  void foo01() {}
+}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+extension E2 on int {
+  void foo02() {}
+}
+''');
+
+    var response = await _getTestCodeSuggestions(r'''
+import 'b.dart';
+ 
+void f() {
+  0.foo0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // `foo01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
+  Future<void> test_notImported_lowerRelevance_extension_setter() async {
+    await _configureWithWorkspaceRoot();
+
+    newFile('$testPackageLibPath/a.dart', content: '''
+extension E1 on int {
+  set foo01(int _) {}
+}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+extension E2 on int {
+  set foo02(int _) {}
+}
+''');
+
+    var response = await _getTestCodeSuggestions(r'''
+import 'b.dart';
+ 
+void f() {
+  0.foo0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // `foo01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
+  Future<void> test_notImported_lowerRelevance_topLevel_class() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+class A01 {}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+class A02 {}
+''');
+
+    await _configureWithWorkspaceRoot();
+
+    var response = await _getTestCodeSuggestions('''
+import 'b.dart';
+
+void f() {
+  A0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 2);
+
+    // `A01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.withElementClass.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('A02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('A01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
+  Future<void> test_notImported_lowerRelevance_topLevel_getter() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+int get foo01 => 0;
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+int get foo02 => 0;
+''');
+
+    await _configureWithWorkspaceRoot();
+
+    var response = await _getTestCodeSuggestions('''
+import 'b.dart';
+
+void f() {
+  foo0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // `foo01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
+  Future<void> test_notImported_lowerRelevance_topLevel_setter() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+set foo01(int _) {}
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+set foo02(int _) {}
+''');
+
+    await _configureWithWorkspaceRoot();
+
+    var response = await _getTestCodeSuggestions('''
+import 'b.dart';
+
+void f() {
+  foo0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // `foo01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
+  Future<void> test_notImported_lowerRelevance_topLevel_variable() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+var foo01 = 0;
+''');
+
+    newFile('$testPackageLibPath/b.dart', content: '''
+var foo02 = 0;
+''');
+
+    await _configureWithWorkspaceRoot();
+
+    var response = await _getTestCodeSuggestions('''
+import 'b.dart';
+
+void f() {
+  foo0^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // `foo01` relevance is decreased because it is not yet imported.
+    check(response).suggestions.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo02')
+        ..libraryUriToImport.isNull,
+      (suggestion) => suggestion
+        ..completion.isEqualTo('foo01')
+        ..libraryUriToImport.isEqualTo('package:test/a.dart'),
+    ]);
+  }
+
   Future<void> test_notImported_pub_dependencies_inLib() async {
     writeTestPackagePubspecYamlFile(r'''
 name: test
@@ -522,7 +772,7 @@
     await _configureWithWorkspaceRoot();
 
     var response = await _getTestCodeSuggestions('''
-import 'a.dart' show A01;
+import 'a.dart' show A02;
 
 void f() {
   A0^
@@ -533,12 +783,16 @@
       ..assertComplete()
       ..hasReplacement(left: 2);
 
+    // Note:
+    // 1. A02 is the first, because it is already imported.
+    // 2. A01 is still suggested, but with lower relevance.
+    // 3. A03 has the same relevance (not tested), but sorted by name.
     check(response).suggestions.withElementClass.matches([
       (suggestion) => suggestion
-        ..completion.isEqualTo('A01')
+        ..completion.isEqualTo('A02')
         ..libraryUriToImport.isNull,
       (suggestion) => suggestion
-        ..completion.isEqualTo('A02')
+        ..completion.isEqualTo('A01')
         ..libraryUriToImport.isEqualTo('package:test/a.dart'),
       (suggestion) => suggestion
         ..completion.isEqualTo('A03')
@@ -1371,6 +1625,29 @@
     ]);
   }
 
+  Future<void> test_unprefixed_imported_withPrefix_class() async {
+    await _configureWithWorkspaceRoot();
+
+    var response = await _getTestCodeSuggestions('''
+import 'dart:math' as math;
+
+void f() {
+  Rand^
+}
+''');
+
+    check(response)
+      ..assertComplete()
+      ..hasReplacement(left: 4);
+
+    // No suggestion without the `math` prefix.
+    check(response).suggestions.withElementClass.matches([
+      (suggestion) => suggestion
+        ..completion.isEqualTo('math.Random')
+        ..libraryUriToImport.isNull,
+    ]);
+  }
+
   Future<void> test_unprefixed_sorts_byScore() async {
     await _configureWithWorkspaceRoot();
 
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 3b95fd5..477d52b 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -519,7 +519,7 @@
   "label": "MyAlias",
   "declaringLibraryUri": "package:test/a.dart",
   "element": {
-    "kind": "FUNCTION_TYPE_ALIAS",
+    "kind": "TYPE_ALIAS",
     "name": "MyAlias",
     "location": {
       "file": ${jsonOfPath(path)},
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index aba444c..06e0298 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -1899,6 +1899,7 @@
     0.0,
     0.0,
     0.0,
+    0.0,
     0.0
   ];
 
@@ -1923,6 +1924,7 @@
       double hasDeprecated = 0.0,
       double isConstant = 0.0,
       double isNoSuchMethod = 0.0,
+      double isNotImported = 0.0,
       double keyword = 0.0,
       double startsWithDollar = 0.0,
       double superMatches = 0.0,
@@ -1935,6 +1937,7 @@
       hasDeprecated,
       isConstant,
       isNoSuchMethod,
+      isNotImported,
       keyword,
       startsWithDollar,
       superMatches,
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index 8c78fc5..6f9b09b 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -3051,6 +3051,7 @@
     correctionMessage:
         "Try removing the code point or using the Unicode escape sequence "
         "'\\u{0}'.",
+    hasPublishedDocs: true,
   );
 
   /**
@@ -3096,6 +3097,7 @@
     correctionMessage:
         "Try removing the code point or using the Unicode escape sequence "
         "'\\u{0}'.",
+    hasPublishedDocs: true,
   );
 
   /**
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 8e8b939..e373a74 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -66,6 +66,9 @@
 }
 
 abstract class Timer {
+  factory Timer(Duration duration, void Function() callback) {
+    throw 0;
+  }
   static void run(void callback()) {}
 }
 ''',
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 8507f19..1e292cc 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -16515,7 +16515,7 @@
   TEXT_DIRECTION_CODE_POINT_IN_COMMENT:
     problemMessage: The Unicode code point 'U+{0}' changes the appearance of text from how it's interpreted by the compiler.
     correctionMessage: Try removing the code point or using the Unicode escape sequence '\u{0}'.
-    hasPublishedDocs: false
+    hasPublishedDocs: true
     comment: |-
       Parameters:
       0: the unicode sequence of the code point.
@@ -16555,7 +16555,7 @@
   TEXT_DIRECTION_CODE_POINT_IN_LITERAL:
     problemMessage: The Unicode code point 'U+{0}' changes the appearance of text from how it's interpreted by the compiler.
     correctionMessage: Try removing the code point or using the Unicode escape sequence '\u{0}'.
-    hasPublishedDocs: false
+    hasPublishedDocs: true
     comment: |-
       Parameters:
       0: the unicode sequence of the code point.
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index ea27263..16c003c 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -557,6 +557,9 @@
     js.Program program = js.Program([
       if (isFirst) buildGeneratedBy(),
       if (isFirst) buildDeferredInitializerGlobal(),
+      if (_options.experimentalTrackAllocations)
+        js.js.statement("var allocations = #deferredGlobal['allocations']",
+            {'deferredGlobal': deferredInitializersGlobal}),
       js.js.statement('$deferredInitializersGlobal.current = #', code)
     ]);
 
diff --git a/tools/VERSION b/tools/VERSION
index af0f4b8..f398668 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 39
+PRERELEASE 40
 PRERELEASE_PATCH 0
\ No newline at end of file