Revert "Validate pubspec names after resolution, instead of when parsing (#3956)" (#4006)

This reverts commit 037138e6ea82488a2ec2ca4e190680506fe634db.
diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart
index 8d6dd67..efba10c 100644
--- a/lib/src/entrypoint.dart
+++ b/lib/src/entrypoint.dart
@@ -87,6 +87,7 @@
   ///
   /// For a global package, this is the activated package.
   Package get root => _root ??= Package.load(
+        null,
         rootDir,
         cache.sources,
         withPubspecOverrides: true,
@@ -177,6 +178,7 @@
     var packages = {
       for (var packageEntry in packageConfig.nonInjectedPackages)
         packageEntry.name: Package.load(
+          packageEntry.name,
           packageEntry.resolvedRootDir(packageConfigPath),
           cache.sources,
         ),
diff --git a/lib/src/package.dart b/lib/src/package.dart
index eaa41bf..8058dc3 100644
--- a/lib/src/package.dart
+++ b/lib/src/package.dart
@@ -116,13 +116,14 @@
 
   /// Loads the package whose root directory is [packageDir].
   ///
-  /// [expectedName] is the expected name of that package (e.g. the name given
-  /// in the dependency), or `null` if the package being loaded is the
-  /// entrypoint package.
+  /// [name] is the expected name of that package (e.g. the name given in the
+  /// dependency), or `null` if the package being loaded is the entrypoint
+  /// package.
   ///
   /// `pubspec_overrides.yaml` is only loaded if [withPubspecOverrides] is
   /// `true`.
   factory Package.load(
+    String? name,
     String dir,
     SourceRegistry sources, {
     bool withPubspecOverrides = false,
@@ -130,6 +131,7 @@
     final pubspec = Pubspec.load(
       dir,
       sources,
+      expectedName: name,
       allowOverridesFile: withPubspecOverrides,
     );
     return Package._(dir, pubspec);
diff --git a/lib/src/pubspec.dart b/lib/src/pubspec.dart
index f1ec472..f8bfe8c 100644
--- a/lib/src/pubspec.dart
+++ b/lib/src/pubspec.dart
@@ -207,11 +207,15 @@
 
   /// Loads the pubspec for a package located in [packageDir].
   ///
+  /// If [expectedName] is passed and the pubspec doesn't have a matching name
+  /// field, this will throw a [SourceSpanApplicationException].
+  ///
   /// If [allowOverridesFile] is `true` [pubspecOverridesFilename] is loaded and
   /// is allowed to override dependency_overrides from `pubspec.yaml`.
   factory Pubspec.load(
     String packageDir,
     SourceRegistry sources, {
+    String? expectedName,
     bool allowOverridesFile = false,
   }) {
     var pubspecPath = path.join(packageDir, pubspecYamlFilename);
@@ -233,6 +237,7 @@
     return Pubspec.parse(
       readTextFile(pubspecPath),
       sources,
+      expectedName: expectedName,
       location: path.toUri(pubspecPath),
       overridesFileContents: overridesFileContents,
       overridesLocation: path.toUri(overridesPath),
@@ -273,11 +278,15 @@
   /// Returns a Pubspec object for an already-parsed map representing its
   /// contents.
   ///
+  /// If [expectedName] is passed and the pubspec doesn't have a matching name
+  /// field, this will throw a [PubspecError].
+  ///
   /// [location] is the location from which this pubspec was loaded.
   Pubspec.fromMap(
     Map fields,
     this._sources, {
     YamlMap? overridesFields,
+    String? expectedName,
     Uri? location,
   })  : _overridesFileFields = overridesFields,
         _includeDefaultSdkConstraint = true,
@@ -288,7 +297,18 @@
           fields is YamlMap
               ? fields
               : YamlMap.wrap(fields, sourceUrl: location),
-        );
+        ) {
+    // If [expectedName] is passed, ensure that the actual 'name' field exists
+    // and matches the expectation.
+    if (expectedName == null) return;
+    if (name == expectedName) return;
+
+    throw SourceSpanApplicationException(
+      '"name" field doesn\'t match expected name '
+      '"$expectedName".',
+      this.fields.nodes['name']!.span,
+    );
+  }
 
   /// Parses the pubspec stored at [location] whose text is [contents].
   ///
@@ -297,6 +317,7 @@
   factory Pubspec.parse(
     String contents,
     SourceRegistry sources, {
+    String? expectedName,
     Uri? location,
     String? overridesFileContents,
     Uri? overridesLocation,
@@ -318,6 +339,7 @@
       pubspecMap,
       sources,
       overridesFields: overridesFileMap,
+      expectedName: expectedName,
       location: location,
     );
   }
diff --git a/lib/src/solver/result.dart b/lib/src/solver/result.dart
index bfb7dbe..fb8f2e5 100644
--- a/lib/src/solver/result.dart
+++ b/lib/src/solver/result.dart
@@ -4,9 +4,7 @@
 
 import 'package:collection/collection.dart';
 import 'package:pub_semver/pub_semver.dart';
-import 'package:yaml/yaml.dart';
 
-import '../exceptions.dart';
 import '../http.dart';
 import '../io.dart';
 import '../lock_file.dart';
@@ -78,7 +76,6 @@
         return id;
       }),
     );
-    await _validatePubspecNames(cache);
 
     // Invariant: the content-hashes in PUB_CACHE matches those provided by the
     // server.
@@ -110,39 +107,6 @@
     );
   }
 
-  /// Validate that all dependencies in [packages] refer to a package that has the
-  /// expected name.
-  ///
-  /// Throws an ApplicationException if there is a mismatch.
-  Future<void> _validatePubspecNames(
-    SystemCache cache,
-  ) async {
-    for (final id in packages) {
-      final pubspec = pubspecs[id.name]!;
-      final validatedNames = <String>{};
-      for (final dependency in [
-        ...pubspec.dependencies.keys,
-        if (id.isRoot) ...pubspec.devDependencies.keys,
-      ]) {
-        if (!validatedNames.add(dependency)) continue;
-        final dependencyPubspec = pubspecs[dependency]!;
-
-        if (dependencyPubspec.name != dependency) {
-          // Find the span for the reference.
-          final key = pubspec.dependencies.containsKey(dependency)
-              ? 'dependencies'
-              : 'dev_dependencies';
-          final dependencyNode = (pubspec.fields.nodes[key] as YamlMap)
-              .nodes[dependency] as YamlNode;
-          throw SourceSpanApplicationException(
-            'Expected to find package "${log.bold(dependency)}", found package "${log.bold(dependencyPubspec.name)}".',
-            dependencyNode.span,
-          );
-        }
-      }
-    }
-  }
-
   final LockFile _previousLockFile;
 
   /// Returns the names of all packages that were changed.
diff --git a/lib/src/source/cached.dart b/lib/src/source/cached.dart
index b57f3b5..933b08c 100644
--- a/lib/src/source/cached.dart
+++ b/lib/src/source/cached.dart
@@ -29,7 +29,7 @@
   Future<Pubspec> doDescribe(PackageId id, SystemCache cache) async {
     var packageDir = getDirectoryInCache(id, cache);
     if (fileExists(path.join(packageDir, 'pubspec.yaml'))) {
-      return Pubspec.load(packageDir, cache.sources);
+      return Pubspec.load(packageDir, cache.sources, expectedName: id.name);
     }
 
     return await describeUncached(id, cache);
diff --git a/lib/src/source/git.dart b/lib/src/source/git.dart
index bc5470b..367f7a9 100644
--- a/lib/src/source/git.dart
+++ b/lib/src/source/git.dart
@@ -336,6 +336,7 @@
         cache,
       ),
       cache.sources,
+      expectedName: ref.name,
     );
   }
 
@@ -427,7 +428,7 @@
 
             var packageDir = p.join(revisionCachePath, relative);
             try {
-              return Package.load(packageDir, cache.sources);
+              return Package.load(null, packageDir, cache.sources);
             } catch (error, stackTrace) {
               log.error('Failed to load package', error, stackTrace);
               var name = p.basename(revisionCachePath).split('-').first;
diff --git a/lib/src/source/hosted.dart b/lib/src/source/hosted.dart
index 6d3d0bd..e99ee52 100644
--- a/lib/src/source/hosted.dart
+++ b/lib/src/source/hosted.dart
@@ -396,6 +396,7 @@
       var pubspec = Pubspec.fromMap(
         pubspecData,
         cache.sources,
+        expectedName: ref.name,
         location: location,
       );
       final archiveSha256 = map['archive_sha256'];
@@ -956,7 +957,7 @@
         var packages = <Package>[];
         for (var entry in listDir(serverDir)) {
           try {
-            packages.add(Package.load(entry, cache.sources));
+            packages.add(Package.load(null, entry, cache.sources));
           } catch (error, stackTrace) {
             log.error('Failed to load package', error, stackTrace);
             final id = _idForBasename(
@@ -1063,7 +1064,7 @@
         .where(_looksLikePackageDir)
         .map((entry) {
           try {
-            return Package.load(entry, cache.sources);
+            return Package.load(null, entry, cache.sources);
           } catch (error, stackTrace) {
             log.fine('Failed to load package from $entry:\n'
                 '$error\n'
diff --git a/lib/src/source/path.dart b/lib/src/source/path.dart
index e2b3ef9..f881b8e 100644
--- a/lib/src/source/path.dart
+++ b/lib/src/source/path.dart
@@ -168,7 +168,7 @@
       throw ArgumentError('Wrong source');
     }
     var dir = _validatePath(ref.name, description);
-    return Pubspec.load(dir, cache.sources);
+    return Pubspec.load(dir, cache.sources, expectedName: ref.name);
   }
 
   @override
diff --git a/lib/src/source/sdk.dart b/lib/src/source/sdk.dart
index 3b391f6..d37c13e 100644
--- a/lib/src/source/sdk.dart
+++ b/lib/src/source/sdk.dart
@@ -89,8 +89,11 @@
   ///
   /// Throws a [PackageNotFoundException] if [ref]'s SDK is unavailable or
   /// doesn't contain the package.
-  Pubspec _loadPubspec(PackageRef ref, SystemCache cache) =>
-      Pubspec.load(_verifiedPackagePath(ref), cache.sources);
+  Pubspec _loadPubspec(PackageRef ref, SystemCache cache) => Pubspec.load(
+        _verifiedPackagePath(ref),
+        cache.sources,
+        expectedName: ref.name,
+      );
 
   /// Returns the path for the given [ref].
   ///
diff --git a/lib/src/system_cache.dart b/lib/src/system_cache.dart
index 10145fe..ff2b535 100644
--- a/lib/src/system_cache.dart
+++ b/lib/src/system_cache.dart
@@ -112,13 +112,17 @@
   ///
   /// Throws an [ArgumentError] if [id] has an invalid source.
   Package load(PackageId id) {
-    return Package.load(getDirectory(id), sources);
+    return Package.load(id.name, getDirectory(id), sources);
   }
 
   Package loadCached(PackageId id) {
     final source = id.description.description.source;
     if (source is CachedSource) {
-      return Package.load(source.getDirectoryInCache(id, this), sources);
+      return Package.load(
+        id.name,
+        source.getDirectoryInCache(id, this),
+        sources,
+      );
     } else {
       throw ArgumentError('Call only on Cached ids.');
     }
diff --git a/test/ascii_tree_test.dart b/test/ascii_tree_test.dart
index b406f72..d0a921b 100644
--- a/test/ascii_tree_test.dart
+++ b/test/ascii_tree_test.dart
@@ -61,9 +61,11 @@
         file('path.dart', bytes(100)),
       ]),
     ]).create();
-    var files =
-        Package.load(path(appPath), (name) => throw UnimplementedError())
-            .listFiles();
+    var files = Package.load(
+      null,
+      path(appPath),
+      (name) => throw UnimplementedError(),
+    ).listFiles();
     ctx.expectNextSection(
       tree.fromFiles(files, baseDir: path(appPath), showFileSizes: true),
     );
diff --git a/test/directory_option_test.dart b/test/directory_option_test.dart
index 4568eac..da0505e 100644
--- a/test/directory_option_test.dart
+++ b/test/directory_option_test.dart
@@ -50,7 +50,7 @@
         pubspec({
           'name': 'example',
           'dependencies': {
-            'test_pkg': {'path': '../'},
+            'myapp': {'path': '../'}, // Wrong name of dependency
           },
         }),
       ]),
diff --git a/test/get/git/dependency_name_match_pubspec_test.dart b/test/get/git/dependency_name_match_pubspec_test.dart
index b048f86..2dcf169 100644
--- a/test/get/git/dependency_name_match_pubspec_test.dart
+++ b/test/get/git/dependency_name_match_pubspec_test.dart
@@ -28,9 +28,8 @@
     ]).create();
 
     await pubGet(
-      error: contains(
-        'Expected to find package "weirdname", found package "foo".',
-      ),
+      error: contains('"name" field doesn\'t match expected name '
+          '"weirdname".'),
       exitCode: exit_codes.DATA,
     );
   });
diff --git a/test/pubspec_test.dart b/test/pubspec_test.dart
index c06ca21..7af4b2d 100644
--- a/test/pubspec_test.dart
+++ b/test/pubspec_test.dart
@@ -15,6 +15,9 @@
   group('parse()', () {
     final sources = SystemCache().sources;
 
+    var throwsPubspecException =
+        throwsA(const TypeMatcher<SourceSpanApplicationException>());
+
     void expectPubspecException(
       String contents,
       void Function(Pubspec) fn, [
@@ -38,6 +41,24 @@
       Pubspec.parse('version: not a semver', sources);
     });
 
+    test(
+        "eagerly throws an error if the pubspec name doesn't match the "
+        'expected name', () {
+      expect(
+        () => Pubspec.parse('name: foo', sources, expectedName: 'bar'),
+        throwsPubspecException,
+      );
+    });
+
+    test(
+        "eagerly throws an error if the pubspec doesn't have a name and an "
+        'expected name is passed', () {
+      expect(
+        () => Pubspec.parse('{}', sources, expectedName: 'bar'),
+        throwsPubspecException,
+      );
+    });
+
     test('allows a version constraint for dependencies', () {
       var pubspec = Pubspec.parse(
         '''
diff --git a/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt b/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
index c69e9e2..e4da8be 100644
--- a/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
+++ b/test/testdata/goldens/directory_option_test/commands taking a --directory~-C parameter work.txt
@@ -59,9 +59,12 @@
 ## Section 6
 $ pub get bar -C 'myapp/example2'
 Resolving dependencies in myapp/example2...
-+ foo 1.0.0
-+ test_pkg 1.0.0 from path myapp
-Changed 2 dependencies in myapp/example2!
+[STDERR] Error on line 1, column 9 of myapp/pubspec.yaml: "name" field doesn't match expected name "myapp".
+[STDERR]   ╷
+[STDERR] 1 │ {"name":"test_pkg","version":"1.0.0","homepage":"https://pub.dev","description":"A package, I guess.","environment":{"sdk":">=3.1.2 <=3.2.0"}, dependencies: { foo: ^1.0.0}}
+[STDERR]   │         ^^^^^^^^^^
+[STDERR]   ╵
+[EXIT CODE] 65
 
 -------------------------------- END OF OUTPUT ---------------------------------
 
diff --git a/test/upgrade/git/upgrade_to_incompatible_pubspec_test.dart b/test/upgrade/git/upgrade_to_incompatible_pubspec_test.dart
index 711c344..b45a56f 100644
--- a/test/upgrade/git/upgrade_to_incompatible_pubspec_test.dart
+++ b/test/upgrade/git/upgrade_to_incompatible_pubspec_test.dart
@@ -42,7 +42,7 @@
     ).commit();
 
     await pubUpgrade(
-      error: contains('Expected to find package "foo", found package "zoo".'),
+      error: contains('"name" field doesn\'t match expected name "foo".'),
       exitCode: exit_codes.DATA,
     );