Issue 45141. Check for loadLibrary() using namespace.

Bug: https://github.com/dart-lang/sdk/issues/45141
Change-Id: Ifb0825d66a560d0136873942f9666d3dc630b6c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/189320
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index ca4d836..20e2720 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -53,7 +53,6 @@
       properties['isStatic'] = element.isStatic;
     }
     if (element is CompilationUnitElement) {
-      properties['hasLoadLibraryFunction'] = element.hasLoadLibraryFunction;
       properties['source'] = element.source;
     }
     if (element is ConstFieldElementImpl) {
@@ -109,7 +108,6 @@
       properties['definingCompilationUnit'] = element.definingCompilationUnit;
       properties['entryPoint'] = element.entryPoint;
       properties['hasExtUri'] = element.hasExtUri;
-      properties['hasLoadLibraryFunction'] = element.hasLoadLibraryFunction;
       properties['isBrowserApplication'] = element.isBrowserApplication;
       properties['isDartAsync'] = element.isDartAsync;
       properties['isDartCore'] = element.isDartCore;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index fb8ce6f..85778f6 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -408,6 +408,7 @@
 
   /// Return `true` if this compilation unit defines a top-level function named
   /// `loadLibrary`.
+  @Deprecated('Not useful for clients')
   bool get hasLoadLibraryFunction;
 
   /// Return the [LineInfo] for the [source], or `null` if not computed yet.
@@ -1328,6 +1329,7 @@
 
   /// Return `true` if this library defines a top-level function named
   /// `loadLibrary`.
+  @Deprecated('Not useful for clients')
   bool get hasLoadLibraryFunction;
 
   /// Return an identifier that uniquely identifies this element among the
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 30e8681..45df3f4 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1338,6 +1338,7 @@
   @override
   int get hashCode => source.hashCode;
 
+  @Deprecated('Not useful for clients')
   @override
   bool get hasLoadLibraryFunction {
     List<FunctionElement> functions = this.functions;
@@ -5029,6 +5030,7 @@
     setModifier(Modifier.HAS_EXT_URI, hasExtUri);
   }
 
+  @Deprecated('Not useful for clients')
   @override
   bool get hasLoadLibraryFunction {
     for (int i = 0; i < units.length; i++) {
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 9b54f4e..e68cf25 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -1130,11 +1130,15 @@
   /// See [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION].
   bool _checkForLoadLibraryFunction(
       ImportDirective node, ImportElement importElement) {
-    LibraryElement? importedLibrary = importElement.importedLibrary;
-    if (importedLibrary == null) {
+    var importedLibrary = importElement.importedLibrary;
+    var prefix = importElement.prefix;
+    if (importedLibrary == null || prefix == null) {
       return false;
     }
-    if (importedLibrary.hasLoadLibraryFunction) {
+    var importNamespace = importElement.namespace;
+    var loadLibraryElement = importNamespace.getPrefixed(
+        prefix.name, FunctionElement.LOAD_LIBRARY_NAME);
+    if (loadLibraryElement != null) {
       _errorReporter.reportErrorForNode(
           HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
           node,
diff --git a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
index 040fe91..5befb60 100644
--- a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../generated/test_support.dart';
 import '../dart/resolution/context_collection_resolution.dart';
 
 main() {
@@ -18,59 +17,90 @@
 class ImportDeferredLibraryWithLoadFunctionTest
     extends PubPackageResolutionTest {
   test_deferredImport_withLoadLibraryFunction() async {
-    newFile('$testPackageLibPath/lib1.dart', content: r'''
-library lib1;
-loadLibrary() {}
-f() {}''');
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void loadLibrary() {}
+void f() {}
+''');
 
-    newFile('$testPackageLibPath/lib2.dart', content: r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }''');
-
-    await _resolveFile('$testPackageLibPath/lib1.dart');
-    await _resolveFile('$testPackageLibPath/lib2.dart', [
-      error(HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, 14, 36),
+    await assertErrorsInCode(r'''
+import 'a.dart' deferred as p;
+void main() {
+  p.f();
+}
+''', [
+      error(HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, 0, 30),
     ]);
   }
 
+  test_deferredImport_withLoadLibraryFunction_hide() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void loadLibrary() {}
+void f() {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' deferred as p hide loadLibrary;
+void main() {
+  p.f();
+}
+''');
+  }
+
+  test_deferredImport_withLoadLibraryFunction_hide2() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void loadLibrary() {}
+void f() {}
+void f2() {}
+''');
+
+    await assertErrorsInCode(r'''
+import 'a.dart' deferred as p hide f2;
+void main() {
+  p.f();
+}
+''', [
+      error(HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, 0, 38),
+    ]);
+  }
+
+  test_deferredImport_withLoadLibraryFunction_show() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void loadLibrary() {}
+void f() {}
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart' deferred as p show f;
+void main() {
+  p.f();
+}
+''');
+  }
+
   test_deferredImport_withoutLoadLibraryFunction() async {
-    newFile('$testPackageLibPath/lib1.dart', content: r'''
-library lib1;
-f() {}''');
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void f() {}
+''');
 
-    newFile('$testPackageLibPath/lib2.dart', content: r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }''');
-
-    await _resolveFile('$testPackageLibPath/lib1.dart');
-    await _resolveFile('$testPackageLibPath/lib2.dart');
+    await assertNoErrorsInCode(r'''
+import 'a.dart' deferred as p;
+void main() {
+  p.f();
+}
+''');
   }
 
   test_nonDeferredImport_withLoadLibraryFunction() async {
-    newFile('$testPackageLibPath/lib1.dart', content: r'''
-library lib1;
-loadLibrary() {}
-f() {}''');
+    newFile('$testPackageLibPath/a.dart', content: r'''
+void loadLibrary() {}
+void f() {}
+''');
 
-    newFile('$testPackageLibPath/lib2.dart', content: r'''
-library root;
-import 'lib1.dart' as lib1;
-main() { lib1.f(); }''');
-
-    await _resolveFile('$testPackageLibPath/lib1.dart');
-    await _resolveFile('$testPackageLibPath/lib2.dart');
-  }
-
-  /// Resolve the file with the given [path].
-  ///
-  /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
-  Future<void> _resolveFile(
-    String path, [
-    List<ExpectedError> expectedErrors = const [],
-  ]) async {
-    result = await resolveFile(convertPath(path));
-    assertErrorsInResolvedUnit(result, expectedErrors);
+    await assertNoErrorsInCode(r'''
+import 'a.dart' as p;
+void main() {
+  p.f();
+}
+''');
   }
 }