Version 2.14.0-362.0.dev

Merge commit 'cb3a9b0043d336c3a0864edaa13699d17ffd807c' into 'dev'
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index e6b028b..293559f 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -55,6 +55,7 @@
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 import 'package:http/http.dart' as http;
+import 'package:process/process.dart';
 import 'package:telemetry/crash_reporting.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
 import 'package:watcher/watcher.dart';
@@ -130,6 +131,7 @@
     CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
     InstrumentationService instrumentationService, {
     http.Client? httpClient,
+    ProcessManager? processManager,
     RequestStatisticsHelper? requestStatistics,
     DiagnosticServer? diagnosticServer,
     this.detachableFileSystemManager,
@@ -143,6 +145,7 @@
           baseResourceProvider,
           instrumentationService,
           httpClient,
+          processManager,
           NotificationManager(channel, baseResourceProvider.pathContext),
           requestStatistics: requestStatistics,
           enableBazelWatcher: enableBazelWatcher,
@@ -429,9 +432,11 @@
     bool isPubspec(String filePath) =>
         file_paths.isPubspecYaml(resourceProvider.pathContext, filePath);
 
-    // When a pubspec is opened, trigger package name caching for completion.
-    if (!pubPackageService.isRunning && files.any(isPubspec)) {
-      pubPackageService.beginPackageNamePreload();
+    // When pubspecs are opened, trigger pre-loading of pub package names and
+    // versions.
+    final pubspecs = files.where(isPubspec).toList();
+    if (pubspecs.isNotEmpty) {
+      pubPackageService.beginCachePreloads(pubspecs);
     }
 
     priorityFiles.clear();
@@ -688,6 +693,18 @@
   }
 
   @override
+  void pubspecChanged(String pubspecPath) {
+    analysisServer.pubPackageService.fetchPackageVersionsViaPubOutdated(
+        pubspecPath,
+        pubspecWasModified: true);
+  }
+
+  @override
+  void pubspecRemoved(String pubspecPath) {
+    analysisServer.pubPackageService.flushPackageCaches(pubspecPath);
+  }
+
+  @override
   void recordAnalysisErrors(String path, List<AnalysisError> errors) {
     filesToFlush.add(path);
     _notificationManager.recordAnalysisErrors(
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 6a351b1..c39dbe8 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -19,6 +19,7 @@
 import 'package:analysis_server/src/services/completion/dart/extension_cache.dart';
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/pub/pub_api.dart';
+import 'package:analysis_server/src/services/pub/pub_command.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
@@ -52,6 +53,7 @@
 import 'package:collection/collection.dart';
 import 'package:http/http.dart' as http;
 import 'package:meta/meta.dart';
+import 'package:process/process.dart';
 
 /// Implementations of [AbstractAnalysisServer] implement a server that listens
 /// on a [CommunicationChannel] for analysis messages and process them.
@@ -152,14 +154,26 @@
     ResourceProvider baseResourceProvider,
     this.instrumentationService,
     http.Client? httpClient,
+    ProcessManager? processManager,
     this.notificationManager, {
     this.requestStatistics,
     bool enableBazelWatcher = false,
   })  : resourceProvider = OverlayResourceProvider(baseResourceProvider),
         pubApi = PubApi(instrumentationService, httpClient,
             Platform.environment['PUB_HOSTED_URL']) {
-    pubPackageService =
-        PubPackageService(instrumentationService, baseResourceProvider, pubApi);
+    // We can only use a LocalProcessManager to run pub commands when backed by
+    // a real file system, otherwise we may try to run commands in folders that
+    // don't really exist. If processManager was supplied, it's likely a mock
+    // from a test in which case the pub command should still be created.
+    if (baseResourceProvider is PhysicalResourceProvider) {
+      processManager ??= LocalProcessManager();
+    }
+    final pubCommand = processManager != null
+        ? PubCommand(instrumentationService, processManager)
+        : null;
+
+    pubPackageService = PubPackageService(
+        instrumentationService, baseResourceProvider, pubApi, pubCommand);
     performance = performanceDuringStartup;
 
     pluginManager = PluginManager(
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 721f37c..28509f0 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -122,6 +122,12 @@
   /// TODO(scheglov) Just pass results in here?
   void listenAnalysisDriver(AnalysisDriver driver);
 
+  /// The `pubspec.yaml` at [path] was added/modified.
+  void pubspecChanged(String path);
+
+  /// The `pubspec.yaml` at [path] was removed.
+  void pubspecRemoved(String path);
+
   /// Record error information for the file with the given [path].
   void recordAnalysisErrors(String path, List<protocol.AnalysisError> errors);
 }
@@ -566,12 +572,21 @@
 
     _instrumentationService.logWatchEvent('<unknown>', path, type.toString());
 
+    final isPubpsec = file_paths.isPubspecYaml(pathContext, path);
     if (file_paths.isAnalysisOptionsYaml(pathContext, path) ||
         file_paths.isDotPackages(pathContext, path) ||
         file_paths.isPackageConfigJson(pathContext, path) ||
-        file_paths.isPubspecYaml(pathContext, path) ||
+        isPubpsec ||
         false) {
       _createAnalysisContexts();
+
+      if (isPubpsec) {
+        if (type == ChangeType.REMOVE) {
+          callbacks.pubspecRemoved(path);
+        } else {
+          callbacks.pubspecChanged(path);
+        }
+      }
       return;
     }
 
@@ -727,6 +742,12 @@
   void listenAnalysisDriver(AnalysisDriver driver) {}
 
   @override
+  void pubspecChanged(String pubspecPath) {}
+
+  @override
+  void pubspecRemoved(String pubspecPath) {}
+
+  @override
   void recordAnalysisErrors(String path, List<protocol.AnalysisError> errors) {}
 }
 
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index cac5665..7194102 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -52,6 +52,7 @@
 import 'package:collection/collection.dart';
 import 'package:http/http.dart' as http;
 import 'package:meta/meta.dart';
+import 'package:process/process.dart';
 import 'package:watcher/watcher.dart';
 
 /// Instances of the class [LspAnalysisServer] implement an LSP-based server
@@ -126,6 +127,7 @@
     CrashReportingAttachmentsBuilder crashReportingAttachmentsBuilder,
     InstrumentationService instrumentationService, {
     http.Client? httpClient,
+    ProcessManager? processManager,
     DiagnosticServer? diagnosticServer,
     // Disable to avoid using this in unit tests.
     bool enableBazelWatcher = false,
@@ -137,6 +139,7 @@
           baseResourceProvider,
           instrumentationService,
           httpClient,
+          processManager,
           LspNotificationManager(channel, baseResourceProvider.pathContext),
           enableBazelWatcher: enableBazelWatcher,
         ) {
@@ -184,10 +187,10 @@
       RefactoringWorkspace(driverMap.values, searchEngine);
 
   void addPriorityFile(String filePath) {
-    // When a pubspec is opened, trigger package name caching for completion.
-    if (!pubPackageService.isRunning &&
-        file_paths.isPubspecYaml(resourceProvider.pathContext, filePath)) {
-      pubPackageService.beginPackageNamePreload();
+    // When pubspecs are opened, trigger pre-loading of pub package names and
+    // versions.
+    if (file_paths.isPubspecYaml(resourceProvider.pathContext, filePath)) {
+      pubPackageService.beginCachePreloads([filePath]);
     }
 
     final didAdd = priorityFiles.add(filePath);
@@ -852,6 +855,18 @@
   }
 
   @override
+  void pubspecChanged(String pubspecPath) {
+    analysisServer.pubPackageService.fetchPackageVersionsViaPubOutdated(
+        pubspecPath,
+        pubspecWasModified: true);
+  }
+
+  @override
+  void pubspecRemoved(String pubspecPath) {
+    analysisServer.pubPackageService.flushPackageCaches(pubspecPath);
+  }
+
+  @override
   void recordAnalysisErrors(String path, List<protocol.AnalysisError> errors) {
     final errorsToSend = errors.where(_shouldSendError).toList();
     filesToFlush.add(path);
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 429920f..5f54403 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -49,6 +49,15 @@
   ],
 };
 
+/// Pattern for docComplete text on completion items that can be upgraded to
+/// the "detail" field so that it can be shown more prominently by clients.
+///
+/// This is typically used for labels like _latest compatible_ and _latest_ in
+/// the pubspec version items. These go into docComplete so that they appear
+/// reasonably for non-LSP clients where there is no equivalent of the detail
+/// field.
+final _upgradableDocCompletePattern = RegExp(r'^_([\w ]{0,20})_$');
+
 lsp.Either2<String, lsp.MarkupContent> asStringOrMarkupContent(
     Set<lsp.MarkupKind>? preferredFormats, String content) {
   return preferredFormats == null
@@ -956,7 +965,21 @@
   final insertText = insertTextInfo.first;
   final insertTextFormat = insertTextInfo.last;
   final isMultilineCompletion = insertText.contains('\n');
-  final cleanedDoc = cleanDartdoc(suggestion.docComplete);
+
+  var cleanedDoc = cleanDartdoc(suggestion.docComplete);
+  var detail = getCompletionDetail(suggestion, completionKind,
+      supportsCompletionDeprecatedFlag || supportsDeprecatedTag);
+
+  // To improve the display of some items (like pubspec version numbers),
+  // short labels in the format `_foo_` in docComplete are "upgraded" to the
+  // detail field.
+  final labelMatch = cleanedDoc != null
+      ? _upgradableDocCompletePattern.firstMatch(cleanedDoc)
+      : null;
+  if (labelMatch != null) {
+    cleanedDoc = null;
+    detail = labelMatch.group(1);
+  }
 
   // Because we potentially send thousands of these items, we should minimise
   // the generated JSON as much as possible - for example using nulls in place
@@ -971,8 +994,7 @@
     commitCharacters:
         includeCommitCharacters ? dartCompletionCommitCharacters : null,
     data: resolutionData,
-    detail: getCompletionDetail(suggestion, completionKind,
-        supportsCompletionDeprecatedFlag || supportsDeprecatedTag),
+    detail: detail,
     documentation: cleanedDoc != null
         ? asStringOrMarkupContent(formats, cleanedDoc)
         : null,
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
index 960346f..5d7f681 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/producer.dart
@@ -176,9 +176,11 @@
   const Producer();
 
   /// A utility method used to create a suggestion for the [identifier].
-  CompletionSuggestion identifier(String identifier, {int relevance = 1000}) =>
+  CompletionSuggestion identifier(String identifier,
+          {int relevance = 1000, String? docComplete}) =>
       CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER, relevance,
-          identifier, identifier.length, 0, false, false);
+          identifier, identifier.length, 0, false, false,
+          docComplete: docComplete);
 
   /// A utility method used to create a suggestion for the package [packageName].
   CompletionSuggestion packageName(String packageName,
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
index 724bb6f..a34d791 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/pubspec_generator.dart
@@ -37,18 +37,25 @@
   @override
   Iterable<CompletionSuggestion> suggestions(
       YamlCompletionRequest request) sync* {
-    // TOOD(dantup): Consider supporting async completion requests so this
-    // could call packageDetails() (with a short timeout, and pub retries
-    // disabled). A user that explicitly invokes completion in the location
-    // of a version may be prepared to wait a short period for a web request
-    // to get completion versions (this is also the only way for non-LSP
-    // clients to get them, since there are no resolve calls).
+    final versions = request.pubPackageService
+        ?.cachedPubOutdatedVersions(request.filePath, package);
+    final resolvable = versions?.resolvableVersion;
+    var latest = versions?.latestVersion;
+
+    // If we didn't get a latest version from the "pub outdated" results, we can
+    // use the result from the Pub API if we've called it (this will usually
+    // only be the case for LSP where a resolve() call was sent).
     //
-    // Supporting this will require making the completion async further up.
-    final details = request.pubPackageService?.cachedPackageDetails(package);
-    final version = details?.latestVersion;
-    if (version != null) {
-      yield identifier('^$version');
+    // This allows us (in some cases) to still show version numbers even if the
+    // package was newly added to pubspec and not saved, so not yet in the
+    // "pub outdated" results.
+    latest ??= request.pubPackageService?.cachedPubApiLatestVersion(package);
+
+    if (resolvable != null && resolvable != latest) {
+      yield identifier('^$resolvable', docComplete: '_latest compatible_');
+    }
+    if (latest != null) {
+      yield identifier('^$latest', docComplete: '_latest_');
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/pub/pub_command.dart b/pkg/analysis_server/lib/src/services/pub/pub_command.dart
new file mode 100644
index 0000000..0125066
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/pub/pub_command.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:analyzer/instrumentation/service.dart';
+import 'package:path/path.dart' as path;
+import 'package:process/process.dart';
+
+/// A class for interacting with the `pub` command.
+///
+/// `pub` commands will be queued and not run concurrently.
+class PubCommand {
+  static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
+  final InstrumentationService _instrumentationService;
+  late final ProcessManager _processManager;
+  late final String _pubPath;
+  late final String _pubEnvironmentValue;
+
+  /// Tracks the last queued command to avoid overlapping because pub does not
+  /// do its own locking when accessing the cache.
+  ///
+  /// https://github.com/dart-lang/pub/issues/1178
+  ///
+  /// This does not prevent running concurrently with commands spawned by other
+  /// tools (such as the IDE).
+  var _lastQueuedCommand = Future<void>.value();
+
+  PubCommand(this._instrumentationService, this._processManager) {
+    _pubPath = path.join(
+      path.dirname(Platform.resolvedExecutable),
+      Platform.isWindows ? 'pub.bat' : 'pub',
+    );
+
+    // When calling the `pub` command, we must add an identifier to the
+    // PUB_ENVIRONMENT environment variable (joined with colons).
+    const _pubEnvString = 'analysis_server.pub_api';
+    final existingPubEnv = Platform.environment[_pubEnvironmentKey];
+    _pubEnvironmentValue = [
+      if (existingPubEnv?.isNotEmpty ?? false) existingPubEnv,
+      _pubEnvString,
+    ].join(':');
+  }
+
+  /// Runs `pub outdated --show-all` and returns the results.
+  ///
+  /// If any error occurs executing the command, returns an empty list.
+  Future<List<PubOutdatedPackageDetails>> outdatedVersions(
+      String pubspecPath) async {
+    final packageDirectory = path.dirname(pubspecPath);
+    final result = await _runPubJsonCommand(
+        ['outdated', '--show-all', '--json'],
+        workingDirectory: packageDirectory);
+
+    if (result == null) {
+      return [];
+    }
+
+    final packages =
+        (result['packages'] as List<dynamic>?)?.cast<Map<String, Object?>>();
+    if (packages == null) {
+      return [];
+    }
+
+    return packages
+        .map(
+          (json) => PubOutdatedPackageDetails(
+            json['package'] as String,
+            currentVersion: _version(json, 'current'),
+            latestVersion: _version(json, 'latest'),
+            resolvableVersion: _version(json, 'resolvable'),
+            upgradableVersion: _version(json, 'upgradable'),
+          ),
+        )
+        .toList();
+  }
+
+  /// Runs a pub command and decodes JSON from `stdout`.
+  ///
+  /// Returns null if:
+  ///   - exit code is non-zero
+  ///   - returned text cannot be decoded as JSON
+  Future<Map<String, Object?>?> _runPubJsonCommand(List<String> args,
+      {required String workingDirectory}) async {
+    // Atomically replace the lastQueuedCommand future with our own to ensure
+    // only one command waits on any previous commands future.
+    final completer = Completer<void>();
+    final lastCommand = _lastQueuedCommand;
+    _lastQueuedCommand = completer.future;
+    // And wait for that previous command to finish.
+    await lastCommand.catchError((_) {});
+
+    try {
+      final command = [_pubPath, ...args];
+
+      _instrumentationService.logInfo('Running pub command $command');
+      final result = await _processManager.run(command,
+          workingDirectory: workingDirectory,
+          environment: {_pubEnvironmentKey: _pubEnvironmentValue});
+
+      if (result.exitCode != 0) {
+        _instrumentationService.logError(
+            'pub command returned ${result.exitCode} exit code: ${result.stderr}.');
+        return null;
+      }
+
+      try {
+        final results = jsonDecode(result.stdout);
+        _instrumentationService.logInfo('pub command completed successfully');
+        return results;
+      } catch (e) {
+        _instrumentationService
+            .logError('pub command returned invalid JSON: $e.');
+        return null;
+      }
+    } catch (e) {
+      _instrumentationService.logError('pub command failed to run: $e.');
+      return null;
+    } finally {
+      completer.complete();
+    }
+  }
+
+  String? _version(Map<String, Object?> json, String type) {
+    final versionType = json[type] as Map<String, Object?>?;
+    final version =
+        versionType != null ? versionType['version'] as String? : null;
+    return version;
+  }
+}
+
+class PubOutdatedPackageDetails {
+  final String packageName;
+  final String? currentVersion;
+  final String? latestVersion;
+  final String? resolvableVersion;
+  final String? upgradableVersion;
+
+  PubOutdatedPackageDetails(
+    this.packageName, {
+    required this.currentVersion,
+    required this.latestVersion,
+    required this.resolvableVersion,
+    required this.upgradableVersion,
+  });
+}
diff --git a/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart b/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart
index d0990db..9c99865 100644
--- a/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart
+++ b/pkg/analysis_server/lib/src/services/pub/pub_package_service.dart
@@ -6,10 +6,11 @@
 import 'dart:convert';
 
 import 'package:analysis_server/src/services/pub/pub_api.dart';
+import 'package:analysis_server/src/services/pub/pub_command.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:meta/meta.dart';
+import 'package:path/path.dart' as path;
 
 /// Information about Pub packages that can be converted to/from JSON and
 /// cached to disk.
@@ -130,16 +131,27 @@
 
 /// A service for providing Pub package information.
 ///
-/// Uses a [PubApi] to communicate with Pub and caches to disk using [cacheResourceProvider].
+/// Uses a [PubApi] to communicate with the Pub API and a [PubCommand] to
+/// interact with the local `pub` command.
+///
+/// Expensive results are cached to disk using [resourceProvider].
 class PubPackageService {
   final InstrumentationService _instrumentationService;
   final PubApi _api;
+
+  /// A wrapper over the "pub" command line too.
+  ///
+  /// This can be null when not running on a real file system because it may
+  /// try to interact with folders that don't really exist.
+  final PubCommand? _command;
+
   Timer? _nextPackageNameListRequestTimer;
   Timer? _nextWriteDiskCacheTimer;
 
-  /// [ResourceProvider] used for caching. This should generally be a
-  /// [PhysicalResourceProvider] outside of tests.
-  final ResourceProvider cacheResourceProvider;
+  /// [ResourceProvider] used for accessing the disk for caches and checking
+  /// project types. This should generally be a [PhysicalResourceProvider]
+  /// outside of tests.
+  final ResourceProvider resourceProvider;
 
   /// The current cache of package information. Initially `null`, but
   /// overwritten after first read of cache from disk or fetch from the API.
@@ -148,25 +160,50 @@
 
   int _packageDetailsRequestsInFlight = 0;
 
-  PubPackageService(
-      this._instrumentationService, this.cacheResourceProvider, this._api);
+  /// A cache of version numbers from running the "pub outdated" command used
+  /// for completion in pubspec.yaml.
+  final _pubspecPackageVersions =
+      <String, Map<String, PubOutdatedPackageDetails>>{};
 
-  /// Gets the last set of package results or an empty List if no results.
+  PubPackageService(this._instrumentationService, this.resourceProvider,
+      this._api, this._command);
+
+  /// Gets the last set of package results from the Pub API or an empty List if
+  /// no results.
+  ///
+  /// This data is used for completion of package names in pubspec.yaml
+  /// and for clients that support lazy resolution of completion items may also
+  /// include their descriptions and/or version numbers.
   List<PubPackage> get cachedPackages =>
       packageCache?.packages.values.toList() ?? [];
 
-  bool get isRunning => _nextPackageNameListRequestTimer != null;
+  @visibleForTesting
+  bool get isPackageNamesTimerRunning =>
+      _nextPackageNameListRequestTimer != null;
 
   @visibleForTesting
   File get packageCacheFile {
-    final cacheFolder = cacheResourceProvider
+    final cacheFolder = resourceProvider
         .getStateLocation('.pub-package-details-cache')!
       ..create();
     return cacheFolder.getChildAssumingFile('packages.json');
   }
 
-  /// Begin a request to pre-load the package name list.
+  /// Begins preloading caches for package names and pub versions.
+  void beginCachePreloads(List<String> pubspecs) {
+    beginPackageNamePreload();
+    for (final pubspec in pubspecs) {
+      fetchPackageVersionsViaPubOutdated(pubspec, pubspecWasModified: false);
+    }
+  }
+
+  /// Begin a timer to pre-load and update the package name list if one has not
+  /// already been started.
   void beginPackageNamePreload() {
+    if (isPackageNamesTimerRunning) {
+      return;
+    }
+
     // If first time, try to read from disk.
     var cache = packageCache;
     if (cache == null) {
@@ -179,11 +216,69 @@
         Timer(cache.cacheTimeRemaining, _fetchFromServer);
   }
 
-  /// Gets the cached package details for package [packageName].
+  /// Gets the latest cached package version fetched from the Pub API for the
+  /// package [packageName].
+  String? cachedPubApiLatestVersion(String packageName) =>
+      packageCache?.packages[packageName]?.latestVersion;
+
+  /// Gets the package versions cached using "pub outdated" for the package
+  /// [packageName] for the project using [pubspecPath].
   ///
-  /// Returns null if no package details are cached.
-  PubPackage? cachedPackageDetails(String packageName) =>
-      packageCache?.packages[packageName];
+  /// Versions in here might only be available for packages that are in the
+  /// pubspec on disk. Newly-added packages in the overlay might not be
+  /// available.
+  PubOutdatedPackageDetails? cachedPubOutdatedVersions(
+      String pubspecPath, String packageName) {
+    final pubspecCache = _pubspecPackageVersions[pubspecPath];
+    return pubspecCache != null ? pubspecCache[packageName] : null;
+  }
+
+  /// Begin a request to pre-load package versions using the "pub outdated"
+  /// command.
+  ///
+  /// If [pubspecWasModified] is true, the command will always be run. Otherwise it
+  /// will only be run if data is not already cached.
+  Future<void> fetchPackageVersionsViaPubOutdated(String pubspecPath,
+      {required bool pubspecWasModified}) async {
+    final pubCommand = _command;
+    if (pubCommand == null) {
+      return;
+    }
+
+    // If we already have a cache for the file and it was not modified (only
+    // opened) we do not need to re-run the command.
+    if (!pubspecWasModified &&
+        _pubspecPackageVersions.containsKey(pubspecPath)) {
+      return;
+    }
+
+    // Check if this pubspec is inside a DEPS-managed folder, and if so
+    // just cache an empty set of results since Pub is not managing
+    // dependencies.
+    if (_hasAncestorDEPSFile(pubspecPath)) {
+      _pubspecPackageVersions.putIfAbsent(pubspecPath, () => {});
+      return;
+    }
+
+    final results = await pubCommand.outdatedVersions(pubspecPath);
+    final cache = _pubspecPackageVersions.putIfAbsent(pubspecPath, () => {});
+    for (final package in results) {
+      // We use the versions from the "pub outdated" results but only cache them
+      // in-memory for this specific pubspec, as the resolved version may be
+      // restricted by constraints/dependencies in the pubspec. The "pub"
+      // command does caching of the JSON versions to make "pub outdated" fast.
+      cache[package.packageName] = package;
+    }
+  }
+
+  /// Clears package caches for [pubspecPath].
+  ///
+  /// Does not remove other caches that are not pubspec-specific (for example
+  /// the latest version pulled directly from the Pub API independant of
+  /// pubspec).
+  Future<void> flushPackageCaches(String pubspecPath) async {
+    _pubspecPackageVersions.remove(pubspecPath);
+  }
 
   /// Gets package details for package [packageName].
   ///
@@ -267,6 +362,19 @@
     }
   }
 
+  /// Checks whether there is a DEPS file in any folder walking up from the
+  /// pubspec at [pubspecPath].
+  bool _hasAncestorDEPSFile(String pubspecPath) {
+    var folder = path.dirname(pubspecPath);
+    do {
+      if (resourceProvider.getFile(path.join(folder, 'DEPS')).exists) {
+        return true;
+      }
+      folder = path.dirname(folder);
+    } while (folder != path.dirname(folder));
+    return false;
+  }
+
   /// Writes the package cache to disk after
   /// [PackageDetailsCache._writeCacheDebounceDuration] has elapsed, restarting
   /// the timer each time this method is called.
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 5629eb1..1c8f241 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -24,6 +24,8 @@
   linter: any
   meta:
     path: ../meta
+  process:
+    path: ../../third_party/pkg/process
   stream_channel: any
   telemetry:
     path: ../telemetry
diff --git a/pkg/analysis_server/test/lsp/completion.dart b/pkg/analysis_server/test/lsp/completion.dart
index 75c85b1..6d70a26 100644
--- a/pkg/analysis_server/test/lsp/completion.dart
+++ b/pkg/analysis_server/test/lsp/completion.dart
@@ -8,6 +8,9 @@
 import 'server_abstract.dart';
 
 mixin CompletionTestMixin on AbstractLspAnalysisServerTest {
+  /// The last set of completion results fetched.
+  List<CompletionItem> completionResults = [];
+
   int sortTextSorter(CompletionItem item1, CompletionItem item2) =>
       (item1.sortText ?? item1.label).compareTo(item2.sortText ?? item2.label);
 
@@ -40,23 +43,24 @@
     if (openCloseFile) {
       await openFile(fileUri, withoutMarkers(content));
     }
-    final res = await getCompletion(fileUri, positionFromMarker(content));
+    completionResults =
+        await getCompletion(fileUri, positionFromMarker(content));
     if (openCloseFile) {
       await closeFile(fileUri);
     }
 
     // Sort the completions by sortText and filter to those we expect, so the ordering
     // can be compared.
-    final sortedResults = res
+    final sortedResults = completionResults
         .where((r) => expectCompletions.contains(r.label))
         .toList()
-          ..sort(sortTextSorter);
+      ..sort(sortTextSorter);
 
     expect(sortedResults.map((item) => item.label), equals(expectCompletions));
 
     // Check the edits apply correctly.
     if (applyEditsFor != null) {
-      var item = res.singleWhere((c) => c.label == applyEditsFor);
+      var item = completionResults.singleWhere((c) => c.label == applyEditsFor);
       final insertFormat = item.insertTextFormat;
 
       if (resolve) {
diff --git a/pkg/analysis_server/test/lsp/completion_yaml_test.dart b/pkg/analysis_server/test/lsp/completion_yaml_test.dart
index 9d26755..b8a9c9a 100644
--- a/pkg/analysis_server/test/lsp/completion_yaml_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_yaml_test.dart
@@ -2,6 +2,8 @@
 // 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 'dart:io';
+
 import 'package:analysis_server/src/services/pub/pub_api.dart';
 import 'package:http/http.dart';
 import 'package:linter/src/rules.dart';
@@ -367,7 +369,7 @@
     );
   }
 
-  Future<void> test_package_version() async {
+  Future<void> test_package_versions_fromApi() async {
     httpClient.sendHandler = (BaseRequest request) async {
       if (request.url.path.startsWith(PubApi.packageNameListPath)) {
         return Response(samplePackageList, 200);
@@ -418,6 +420,163 @@
     );
   }
 
+  Future<void> test_package_versions_fromPubOutdated() async {
+    final json = r'''
+    {
+      "packages": [
+        {
+          "package":    "one",
+          "latest":     { "version": "3.2.1" },
+          "resolvable": { "version": "1.2.4" }
+        }
+      ]
+    }
+    ''';
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, json, '');
+
+    final content = '''
+name: foo
+version: 1.0.0
+
+dependencies:
+  one: ^''';
+
+    final expected = '''
+name: foo
+version: 1.0.0
+
+dependencies:
+  one: ^1.2.4''';
+
+    await initialize();
+    await openFile(pubspecFileUri, withoutMarkers(content));
+    await pumpEventQueue(times: 500);
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: ['^1.2.4', '^3.2.1'],
+      applyEditsFor: '^1.2.4',
+      expectedContent: expected,
+      openCloseFile: false,
+    );
+  }
+
+  Future<void> test_package_versions_fromPubOutdated_afterChange() async {
+    final initialJson = r'''
+    {
+      "packages": [
+        {
+          "package":    "one",
+          "latest":     { "version": "3.2.1" },
+          "resolvable": { "version": "1.2.3" }
+        }
+      ]
+    }
+    ''';
+    final updatedJson = r'''
+    {
+      "packages": [
+        {
+          "package":    "one",
+          "latest":     { "version": "2.1.0" },
+          "resolvable": { "version": "2.3.4" }
+        }
+      ]
+    }
+    ''';
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, initialJson, '');
+
+    final content = '''
+name: foo
+version: 1.0.0
+
+dependencies:
+  one: ^''';
+
+    final expected = '''
+name: foo
+version: 1.0.0
+
+dependencies:
+  one: ^2.3.4''';
+
+    newFile(pubspecFilePath, content: content);
+    await initialize();
+    await openFile(pubspecFileUri, withoutMarkers(content));
+    await pumpEventQueue(times: 500);
+
+    // Modify the underlying file which should trigger an update of the
+    // cached data.
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, updatedJson, '');
+    modifyFile(pubspecFilePath, '$content# trailing comment');
+    await pumpEventQueue(times: 500);
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: ['^2.3.4', '^2.1.0'],
+      applyEditsFor: '^2.3.4',
+      expectedContent: expected,
+      openCloseFile: false,
+    );
+
+    // Also veryify the detail fields were populated as expected.
+    expect(
+      completionResults.singleWhere((c) => c.label == '^2.3.4').detail,
+      equals('latest compatible'),
+    );
+    expect(
+      completionResults.singleWhere((c) => c.label == '^2.1.0').detail,
+      equals('latest'),
+    );
+  }
+
+  Future<void> test_package_versions_fromPubOutdated_afterDelete() async {
+    final initialJson = r'''
+    {
+      "packages": [
+        {
+          "package":    "one",
+          "latest":     { "version": "3.2.1" },
+          "resolvable": { "version": "1.2.3" }
+        }
+      ]
+    }
+    ''';
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, initialJson, '');
+
+    final content = '''
+name: foo
+version: 1.0.0
+
+dependencies:
+  one: ^''';
+
+    newFile(pubspecFilePath, content: content);
+    await initialize();
+    await openFile(pubspecFileUri, withoutMarkers(content));
+    await pumpEventQueue(times: 500);
+
+    // Delete the underlying file which should trigger eviction of the cache.
+    deleteFile(pubspecFilePath);
+    await pumpEventQueue(times: 500);
+
+    await verifyCompletions(
+      pubspecFileUri,
+      content,
+      expectCompletions: [],
+      openCloseFile: false,
+    );
+
+    // There should have been no version numbers.
+    expect(completionResults, isEmpty);
+  }
+
   Future<void> test_topLevel() async {
     final content = '''
 version: 1.0.0
diff --git a/pkg/analysis_server/test/lsp/pub_package_service_test.dart b/pkg/analysis_server/test/lsp/pub_package_service_test.dart
index b00f285..7b4095e 100644
--- a/pkg/analysis_server/test/lsp/pub_package_service_test.dart
+++ b/pkg/analysis_server/test/lsp/pub_package_service_test.dart
@@ -2,10 +2,16 @@
 // 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 'dart:io';
+
 import 'package:analysis_server/src/services/pub/pub_api.dart';
+import 'package:analysis_server/src/services/pub/pub_command.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
 import 'package:analyzer/instrumentation/service.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:collection/collection.dart';
 import 'package:http/http.dart';
+import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -15,6 +21,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(PubApiTest);
+    defineReflectiveTests(PubCommandTest);
     defineReflectiveTests(PubPackageServiceTest);
   });
 }
@@ -78,6 +85,168 @@
 }
 
 @reflectiveTest
+class PubCommandTest with ResourceProviderMixin {
+  late MockProcessManager processManager;
+  late PubCommand pubCommand;
+  late String pubspecPath, pubspec2Path;
+
+  void setUp() {
+    pubspecPath = convertPath('/home/project/pubspec.yaml');
+    pubspec2Path = convertPath('/home/project2/pubspec.yaml');
+    processManager = MockProcessManager();
+    pubCommand =
+        PubCommand(InstrumentationService.NULL_SERVICE, processManager);
+  }
+
+  Future<void> test_doesNotRunConcurrently() async {
+    var isRunning = false;
+    processManager.runHandler = (command, {dir, env}) async {
+      expect(isRunning, isFalse,
+          reason: 'pub commands should not run concurrently');
+      isRunning = true;
+      await pumpEventQueue(times: 500);
+      isRunning = false;
+      return ProcessResult(0, 0, '', '');
+    };
+    await Future.wait([
+      pubCommand.outdatedVersions(pubspecPath),
+      pubCommand.outdatedVersions(pubspecPath),
+    ]);
+  }
+
+  Future<void> test_outdated_args() async {
+    processManager.runHandler = (command, {dir, env}) {
+      var expectedPubPath = path.join(
+        path.dirname(Platform.resolvedExecutable),
+        Platform.isWindows ? 'pub.bat' : 'pub',
+      );
+      expect(
+          command,
+          equals([
+            expectedPubPath,
+            'outdated',
+            '--show-all',
+            '--json',
+          ]));
+      expect(dir, equals(convertPath('/home/project')));
+      expect(
+          env!['PUB_ENVIRONMENT'],
+          anyOf(equals('analysis_server.pub_api'),
+              endsWith(':analysis_server.pub_api')));
+      return ProcessResult(0, 0, '', '');
+    };
+    await pubCommand.outdatedVersions(pubspecPath);
+  }
+
+  Future<void> test_outdated_invalidJson() async {
+    processManager.runHandler = (List<String> command, {dir, env}) =>
+        ProcessResult(1, 0, 'NOT VALID JSON', '');
+    final result = await pubCommand.outdatedVersions(pubspecPath);
+    expect(result, isEmpty);
+  }
+
+  Future<void> test_outdated_missingFields() async {
+    final validJson = r'''
+    {
+      "packages": [
+        {
+          "package":    "foo",
+          "current":    { "version": "1.0.0" },
+          "upgradable": { "version": "2.0.0" },
+          "resolvable": { }
+        }
+      ]
+    }
+    ''';
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, validJson, '');
+    final result = await pubCommand.outdatedVersions(pubspecPath);
+    expect(result, hasLength(1));
+    final package = result.first;
+    expect(package.packageName, equals('foo'));
+    expect(package.currentVersion, equals('1.0.0'));
+    expect(package.upgradableVersion, equals('2.0.0'));
+    expect(package.resolvableVersion, isNull);
+    expect(package.latestVersion, isNull);
+  }
+
+  Future<void> test_outdated_multiplePubspecs() async {
+    final pubspecJson1 = r'''
+    {
+      "packages": [
+        {
+          "package":    "foo",
+          "resolvable": { "version": "1.1.1" }
+        }
+      ]
+    }
+    ''';
+    final pubspecJson2 = r'''
+    {
+      "packages": [
+        {
+          "package":    "foo",
+          "resolvable": { "version": "2.2.2" }
+        }
+      ]
+    }
+    ''';
+
+    processManager.runHandler = (command, {dir, env}) {
+      // Return different json based on the directory we were invoked in.
+      final json =
+          dir == path.dirname(pubspecPath) ? pubspecJson1 : pubspecJson2;
+      return ProcessResult(1, 0, json, '');
+    };
+    final result1 = await pubCommand.outdatedVersions(pubspecPath);
+    final result2 = await pubCommand.outdatedVersions(pubspec2Path);
+    expect(result1.first.resolvableVersion, equals('1.1.1'));
+    expect(result2.first.resolvableVersion, equals('2.2.2'));
+  }
+
+  Future<void> test_outdated_nonZeroExitCode() async {
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 123, '{}', '');
+    final result = await pubCommand.outdatedVersions(pubspecPath);
+    expect(result, isEmpty);
+  }
+
+  Future<void> test_validJson() async {
+    final validJson = r'''
+    {
+      "packages": [
+        {
+          "package":    "foo",
+          "current":    { "version": "1.0.0" },
+          "upgradable": { "version": "2.0.0" },
+          "resolvable": { "version": "3.0.0" },
+          "latest":     { "version": "4.0.0" }
+        },
+        {
+          "package":    "bar",
+          "current":    { "version": "1.0.0" },
+          "upgradable": { "version": "2.0.0" },
+          "resolvable": { "version": "3.0.0" },
+          "latest":     { "version": "4.0.0" }
+        }
+      ]
+    }
+    ''';
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, validJson, '');
+    final result = await pubCommand.outdatedVersions(pubspecPath);
+    expect(result, hasLength(2));
+    result.forEachIndexed((index, package) {
+      expect(package.packageName, equals(index == 0 ? 'foo' : 'bar'));
+      expect(package.currentVersion, equals('1.0.0'));
+      expect(package.upgradableVersion, equals('2.0.0'));
+      expect(package.resolvableVersion, equals('3.0.0'));
+      expect(package.latestVersion, equals('4.0.0'));
+    });
+  }
+}
+
+@reflectiveTest
 class PubPackageServiceTest extends AbstractLspAnalysisServerTest {
   /// A sample API response for package names. This should match the JSON served
   /// at https://pub.dev/api/package-name-completion-data.
@@ -194,13 +363,13 @@
   Future<void> test_packageCache_initializesOnPubspecOpen() async {
     await initialize();
 
-    expect(server.pubPackageService.isRunning, isFalse);
+    expect(server.pubPackageService.isPackageNamesTimerRunning, isFalse);
     expect(server.pubPackageService.packageCache, isNull);
     expectPackages([]);
     await openFile(pubspecFileUri, '');
     await pumpEventQueue();
 
-    expect(server.pubPackageService.isRunning, isTrue);
+    expect(server.pubPackageService.isPackageNamesTimerRunning, isTrue);
     expect(server.pubPackageService.packageCache, isNotNull);
     expectPackages([]);
   }
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index a7a8ea0..dc23575 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -48,6 +48,7 @@
   late MockLspServerChannel channel;
   late TestPluginManager pluginManager;
   late LspAnalysisServer server;
+  late MockProcessManager processManager;
   late MockHttpClient httpClient;
 
   /// The number of context builds that had already occurred the last time
@@ -151,6 +152,7 @@
 
   void setUp() {
     httpClient = MockHttpClient();
+    processManager = MockProcessManager();
     channel = MockLspServerChannel(debugPrintCommunication);
     // Create an SDK in the mock file system.
     MockSdk(resourceProvider: resourceProvider);
@@ -162,7 +164,8 @@
         DartSdkManager(convertPath('/sdk')),
         CrashReportingAttachmentsBuilder.empty,
         InstrumentationService.NULL_SERVICE,
-        httpClient: httpClient);
+        httpClient: httpClient,
+        processManager: processManager);
     server.pluginManager = pluginManager;
 
     projectFolderPath = convertPath('/home/test');
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index d6cfa2c..2bc45fd 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -3,11 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
 
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:http/http.dart' as http;
+import 'package:process/process.dart';
 import 'package:test/test.dart';
 
 /// A [Matcher] that check that the given [Response] has an expected identifier
@@ -47,6 +50,31 @@
   }
 }
 
+class MockProcessManager implements ProcessManager {
+  FutureOr<ProcessResult> Function(List<String> command,
+          {String? dir, Map<String, String>? env})? runHandler =
+      (command, {dir, env}) => throw UnimplementedError();
+
+  @override
+  dynamic noSuchMethod(Invocation invocation) {
+    return super.noSuchMethod(invocation);
+  }
+
+  @override
+  Future<ProcessResult> run(
+    List<dynamic> command, {
+    String? workingDirectory,
+    Map<String, String>? environment,
+    bool includeParentEnvironment = true,
+    bool runInShell = false,
+    Encoding stdoutEncoding = systemEncoding,
+    Encoding stderrEncoding = systemEncoding,
+  }) async {
+    return runHandler!(command.cast<String>(),
+        dir: workingDirectory, env: environment);
+  }
+}
+
 class MockSource implements Source {
   @override
   final String fullName;
diff --git a/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart b/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
index 4f4923f..e6ad1db 100644
--- a/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/yaml/pubspec_generator_test.dart
@@ -2,8 +2,11 @@
 // 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 'dart:io';
+
 import 'package:analysis_server/src/services/completion/yaml/pubspec_generator.dart';
 import 'package:analysis_server/src/services/pub/pub_api.dart';
+import 'package:analysis_server/src/services/pub/pub_command.dart';
 import 'package:analysis_server/src/services/pub/pub_package_service.dart';
 import 'package:analyzer/instrumentation/service.dart';
 import 'package:http/http.dart';
@@ -22,6 +25,7 @@
 @reflectiveTest
 class PubspecGeneratorTest extends YamlGeneratorTest {
   late MockHttpClient httpClient;
+  late MockProcessManager processManager;
 
   late PubPackageService pubPackageService;
 
@@ -34,10 +38,12 @@
 
   void setUp() {
     httpClient = MockHttpClient();
+    processManager = MockProcessManager();
     pubPackageService = PubPackageService(
         InstrumentationService.NULL_SERVICE,
         resourceProvider,
-        PubApi(InstrumentationService.NULL_SERVICE, httpClient, null));
+        PubApi(InstrumentationService.NULL_SERVICE, httpClient, null),
+        PubCommand(InstrumentationService.NULL_SERVICE, processManager));
   }
 
   void tearDown() {
@@ -339,4 +345,46 @@
 ''');
     assertSuggestion('two: ');
   }
+
+  void test_packageVersion() async {
+    final json = r'''
+    {
+      "packages": [
+        {
+          "package":    "one",
+          "latest":     { "version": "3.2.1" },
+          "resolvable": { "version": "1.2.4" }
+        }
+      ]
+    }
+    ''';
+    processManager.runHandler =
+        (command, {dir, env}) => ProcessResult(1, 0, json, '');
+
+    pubPackageService.beginCachePreloads([convertPath('/home/test/$fileName')]);
+    await pumpEventQueue(times: 500);
+
+    getCompletions('''
+dependencies:
+  one: ^
+''');
+    assertSuggestion('^1.2.4');
+    assertSuggestion('^3.2.1');
+  }
+
+  /// Ensure in a repo with a DEPS file like the SDK, we do not run pub
+  /// processes to cache the version numbers.
+  void test_packageVersion_withDEPSfile() async {
+    var didRun = false;
+    processManager.runHandler = (command, {dir, env}) {
+      didRun = true;
+      return ProcessResult(1, 0, '', '');
+    };
+
+    newFile('/home/DEPS');
+    pubPackageService.beginCachePreloads([convertPath('/home/test/$fileName')]);
+    await pumpEventQueue(times: 500);
+
+    expect(didRun, isFalse);
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index e10f9be..1e448ff 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -353,8 +353,7 @@
     }
 
     // Run lints that handle specific node types.
-    unit.accept(LinterVisitor(
-        nodeRegistry, ExceptionHandlingDelegatingAstVisitor.logException));
+    unit.accept(LinterVisitor(nodeRegistry));
 
     // Run visitor based lints.
     if (visitors.isNotEmpty) {
diff --git a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
index 2d5a144..cebd705 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_analyzer.dart
@@ -349,8 +349,7 @@
     }
 
     // Run lints that handle specific node types.
-    unit.accept(LinterVisitor(
-        nodeRegistry, ExceptionHandlingDelegatingAstVisitor.logException));
+    unit.accept(LinterVisitor(nodeRegistry));
 
     // Run visitor based lints.
     if (visitors.isNotEmpty) {
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index df3f994..05926b0 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/services/lint.dart';
 
@@ -16,7 +17,9 @@
   final NodeLintRegistry registry;
   final LintRuleExceptionHandler exceptionHandler;
 
-  LinterVisitor(this.registry, this.exceptionHandler);
+  LinterVisitor(this.registry,
+      [this.exceptionHandler =
+          ExceptionHandlingDelegatingAstVisitor.logException]);
 
   @override
   void visitAdjacentStrings(AdjacentStrings node) {
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 0aa7a6e..fe3d41c 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1049,32 +1049,6 @@
         node, node.receiver, receiverType, selector, arguments, null);
   }
 
-  @override
-  TypeInformation visitMethodInvocation(ir.MethodInvocation node) {
-    Selector selector = _elementMap.getSelector(node);
-    ir.Expression receiver = node.receiver;
-    if (receiver is ir.VariableGet &&
-        receiver.variable.parent is ir.FunctionDeclaration) {
-      // TODO(johnniwinther). This triggers the computation of the mask for the
-      // receiver of the call to `call`. Remove this when the ssa builder
-      // recognizes local function invocation directly.
-      _typeOfReceiver(node, node.receiver);
-      // This is an invocation of a named local function.
-      return _handleLocalFunctionInvocation(
-          node, receiver.variable.parent, node.arguments, selector);
-    }
-
-    TypeInformation receiverType = visit(receiver);
-    ArgumentsTypes arguments = analyzeArguments(node.arguments);
-    if (selector.name == '==') {
-      return _handleEqualsCall(node, node.receiver, receiverType,
-          node.arguments.positional.first, arguments.positional[0]);
-    }
-
-    return _handleMethodInvocation(node, node.receiver, receiverType, selector,
-        arguments, node.interfaceTarget);
-  }
-
   ir.VariableDeclaration _getVariableDeclaration(ir.Expression node) {
     return node is ir.VariableGet ? node.variable : null;
   }
@@ -1671,12 +1645,6 @@
     return _handlePropertyGet(node, node.receiver);
   }
 
-  @override
-  TypeInformation visitPropertyGet(ir.PropertyGet node) {
-    return _handlePropertyGet(node, node.receiver,
-        interfaceTarget: node.interfaceTarget);
-  }
-
   TypeInformation _handlePropertySet(
       ir.Expression node, ir.Expression receiver, ir.Expression value,
       {ir.Member interfaceTarget}) {
@@ -1716,12 +1684,6 @@
   }
 
   @override
-  TypeInformation visitPropertySet(ir.PropertySet node) {
-    return _handlePropertySet(node, node.receiver, node.value,
-        interfaceTarget: node.interfaceTarget);
-  }
-
-  @override
   TypeInformation visitInstanceSet(ir.InstanceSet node) {
     return _handlePropertySet(node, node.receiver, node.value,
         interfaceTarget: node.interfaceTarget);
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 45dea65..defc8a7 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -650,20 +650,17 @@
     // TODO(johnniwinther): Implement the ad-hoc check in ast inferrer? This
     // mimicks that ast inferrer which return `true` for [ast.Send] and
     // non-const [ast.NewExpression].
-    if (initializer is ir.MethodInvocation ||
-        initializer is ir.InstanceInvocation ||
+    if (initializer is ir.InstanceInvocation ||
         initializer is ir.InstanceGetterInvocation ||
         initializer is ir.DynamicInvocation ||
         initializer is ir.FunctionInvocation ||
         initializer is ir.LocalFunctionInvocation ||
         initializer is ir.EqualsNull ||
         initializer is ir.EqualsCall ||
-        initializer is ir.PropertyGet ||
         initializer is ir.InstanceGet ||
         initializer is ir.DynamicGet ||
         initializer is ir.InstanceTearOff ||
         initializer is ir.FunctionTearOff ||
-        initializer is ir.PropertySet ||
         initializer is ir.InstanceSet ||
         initializer is ir.DynamicSet ||
         initializer is ir.StaticInvocation ||
diff --git a/pkg/compiler/lib/src/ir/cached_static_type.dart b/pkg/compiler/lib/src/ir/cached_static_type.dart
index 2aca746..9fdb34b 100644
--- a/pkg/compiler/lib/src/ir/cached_static_type.dart
+++ b/pkg/compiler/lib/src/ir/cached_static_type.dart
@@ -46,17 +46,10 @@
   ir.DartType visitVariableGet(ir.VariableGet node) => _getStaticType(node);
 
   @override
-  ir.DartType visitPropertyGet(ir.PropertyGet node) => _getStaticType(node);
-
-  @override
   ir.DartType visitSuperPropertyGet(ir.SuperPropertyGet node) =>
       _getStaticType(node);
 
   @override
-  ir.DartType visitMethodInvocation(ir.MethodInvocation node) =>
-      _getStaticType(node);
-
-  @override
   ir.DartType visitStaticInvocation(ir.StaticInvocation node) =>
       _getStaticType(node);
 
diff --git a/pkg/compiler/lib/src/ir/runtime_type_analysis.dart b/pkg/compiler/lib/src/ir/runtime_type_analysis.dart
index 2fe49b8..3286fc3 100644
--- a/pkg/compiler/lib/src/ir/runtime_type_analysis.dart
+++ b/pkg/compiler/lib/src/ir/runtime_type_analysis.dart
@@ -90,16 +90,14 @@
 
   /// Returns `true` if [node] is of the form `e.runtimeType`.
   bool isGetRuntimeType(ir.TreeNode node) {
-    return node is ir.PropertyGet &&
+    return node is ir.InstanceGet &&
             node.name.text == Identifiers.runtimeType_ ||
-        node is ir.InstanceGet && node.name.text == Identifiers.runtimeType_ ||
         node is ir.DynamicGet && node.name.text == Identifiers.runtimeType_;
   }
 
   /// Returns `true` if [node] is of the form `e.toString()`.
   bool isInvokeToString(ir.TreeNode node) {
-    return node is ir.MethodInvocation && node.name.text == 'toString' ||
-        node is ir.InstanceInvocation && node.name.text == 'toString';
+    return node is ir.InstanceInvocation && node.name.text == 'toString';
   }
 
   assert(isGetRuntimeType(node));
@@ -427,17 +425,13 @@
 
 /// Returns `true` if [node] is a potential invocation of an Object method.
 bool _isObjectMethodInvocation(ir.TreeNode node) {
-  return node is ir.MethodInvocation ||
-      node is ir.InstanceInvocation ||
-      node is ir.EqualsCall;
+  return node is ir.InstanceInvocation || node is ir.EqualsCall;
 }
 
 /// Returns the [_RuntimeTypeAccess] corresponding to [node] if it is an access
 /// of `.runtimeType`, and `null` otherwise.
 _RuntimeTypeAccess _getRuntimeTypeAccess(ir.TreeNode node) {
-  if (node is ir.PropertyGet && node.name.text == 'runtimeType') {
-    return _RuntimeTypeAccess(node, node.receiver);
-  } else if (node is ir.InstanceGet && node.name.text == 'runtimeType') {
+  if (node is ir.InstanceGet && node.name.text == 'runtimeType') {
     return _RuntimeTypeAccess(node, node.receiver);
   } else if (node is ir.DynamicGet && node.name.text == 'runtimeType') {
     return _RuntimeTypeAccess(node, node.receiver);
@@ -455,10 +449,7 @@
 /// Returns the [_EqualsInvocation] corresponding to [node] if it is a call to
 /// of `==`, and `null` otherwise.
 _EqualsInvocation _getEqualsInvocation(ir.TreeNode node) {
-  if (node is ir.MethodInvocation && node.name.text == '==') {
-    return _EqualsInvocation(
-        node, node.receiver, node.arguments.positional.single);
-  } else if (node is ir.EqualsCall) {
+  if (node is ir.EqualsCall) {
     return _EqualsInvocation(node, node.left, node.right);
   }
   return null;
diff --git a/pkg/compiler/lib/src/ir/scope_visitor.dart b/pkg/compiler/lib/src/ir/scope_visitor.dart
index 075e6aa..6fe6cff 100644
--- a/pkg/compiler/lib/src/ir/scope_visitor.dart
+++ b/pkg/compiler/lib/src/ir/scope_visitor.dart
@@ -1026,35 +1026,6 @@
   }
 
   @override
-  EvaluationComplexity visitMethodInvocation(ir.MethodInvocation node) {
-    node.receiver = _handleExpression(node.receiver);
-    EvaluationComplexity receiverComplexity = _lastExpressionComplexity;
-    ir.TreeNode receiver = node.receiver;
-    if (node.arguments.types.isNotEmpty) {
-      VariableUse usage;
-      if (receiver is ir.VariableGet &&
-          (receiver.variable.parent is ir.LocalFunction)) {
-        usage =
-            new VariableUse.localTypeArgument(receiver.variable.parent, node);
-      } else {
-        usage = new VariableUse.instanceTypeArgument(node);
-      }
-      visitNodesInContext(node.arguments.types, usage);
-    }
-    EvaluationComplexity complexity = visitArguments(node.arguments);
-    ir.Member interfaceTarget = node.interfaceTarget;
-    if (receiverComplexity.combine(complexity).isConstant &&
-        interfaceTarget is ir.Procedure &&
-        interfaceTarget.kind == ir.ProcedureKind.Operator) {
-      // Only operator invocations can be part of constant expressions so we
-      // only try to compute an implicit constant when the receiver and all
-      // arguments are constant - and are used in an operator call.
-      return _evaluateImplicitConstant(node);
-    }
-    return const EvaluationComplexity.lazy();
-  }
-
-  @override
   EvaluationComplexity visitInstanceInvocation(ir.InstanceInvocation node) {
     node.receiver = _handleExpression(node.receiver);
     EvaluationComplexity receiverComplexity = _lastExpressionComplexity;
@@ -1169,16 +1140,6 @@
   }
 
   @override
-  EvaluationComplexity visitPropertyGet(ir.PropertyGet node) {
-    node.receiver = _handleExpression(node.receiver);
-    EvaluationComplexity complexity = _lastExpressionComplexity;
-    if (complexity.isConstant && node.name.text == 'length') {
-      return _evaluateImplicitConstant(node);
-    }
-    return const EvaluationComplexity.lazy();
-  }
-
-  @override
   EvaluationComplexity visitInstanceGet(ir.InstanceGet node) {
     node.receiver = _handleExpression(node.receiver);
     EvaluationComplexity complexity = _lastExpressionComplexity;
@@ -1211,13 +1172,6 @@
   }
 
   @override
-  EvaluationComplexity visitPropertySet(ir.PropertySet node) {
-    node.receiver = _handleExpression(node.receiver);
-    node.value = _handleExpression(node.value);
-    return const EvaluationComplexity.lazy();
-  }
-
-  @override
   EvaluationComplexity visitInstanceSet(ir.InstanceSet node) {
     node.receiver = _handleExpression(node.receiver);
     node.value = _handleExpression(node.value);
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 0ea8c89..1baf922 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -14,7 +14,6 @@
 import 'scope.dart';
 import 'static_type_base.dart';
 import 'static_type_cache.dart';
-import 'util.dart';
 
 /// Enum values for how the target of a static type should be interpreted.
 enum ClassRelation {
@@ -268,28 +267,6 @@
         .substituteType(interfaceTarget.getterType);
   }
 
-  /// Computes the result type of the property access [node] on a receiver of
-  /// type [receiverType].
-  ///
-  /// If the `node.interfaceTarget` is `null` but matches an `Object` member
-  /// it is updated to target this member.
-  ir.DartType _computePropertyGetType(
-      ir.PropertyGet node, ir.DartType receiverType) {
-    node.interfaceTarget ??= _resolveDynamicTarget(receiverType, node.name);
-    ir.Member interfaceTarget = node.interfaceTarget;
-    if (interfaceTarget != null) {
-      return _computeInstanceGetType(receiverType, interfaceTarget);
-    }
-    // Treat the properties of Object specially.
-    String nameString = node.name.text;
-    if (nameString == 'hashCode') {
-      return typeEnvironment.coreTypes.intNonNullableRawType;
-    } else if (nameString == 'runtimeType') {
-      return typeEnvironment.coreTypes.typeNonNullableRawType;
-    }
-    return const ir.DynamicType();
-  }
-
   /// Replaces [original] with [replacement] in the AST and removes cached
   /// expression type information for [original].
   void _replaceExpression(ir.Expression original, ir.Expression replacement) {
@@ -308,23 +285,6 @@
   void handleRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType) {}
 
-  @override
-  ir.DartType visitPropertyGet(ir.PropertyGet node) {
-    ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType resultType = _staticTypeCache._expressionTypes[node] =
-        _computePropertyGetType(node, receiverType);
-    receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
-    if (node.interfaceTarget != null) {
-      handleInstanceGet(node, receiverType, node.interfaceTarget, resultType);
-    } else {
-      handleDynamicGet(node, receiverType, node.name, resultType);
-    }
-    if (node.name.text == Identifiers.runtimeType_) {
-      handleRuntimeTypeGet(receiverType, node);
-    }
-    return resultType;
-  }
-
   void handleRuntimeTypeGet(ir.DartType receiverType, ir.Expression node) {
     RuntimeTypeUseData data =
         computeRuntimeTypeUse(_pendingRuntimeTypeUseData, node);
@@ -461,37 +421,6 @@
   }
 
   @override
-  ir.DartType visitPropertySet(ir.PropertySet node) {
-    ir.DartType receiverType = visitNode(node.receiver);
-    ir.DartType valueType = super.visitPropertySet(node);
-    ir.Member interfaceTarget = node.interfaceTarget;
-    if (interfaceTarget == null) {
-      interfaceTarget = _resolveDynamicSet(receiverType, node.name);
-      if (interfaceTarget != null) {
-        ir.DartType setterType =
-            _computeInstanceSetType(receiverType, interfaceTarget);
-        ir.AsExpression implicitCast =
-            _createImplicitAsIfNeeded(node.value, valueType, setterType);
-        if (implicitCast != null) {
-          node.value = implicitCast..parent = node;
-          // Visit the newly created as expression; the original value has
-          // already been visited.
-          handleAsExpression(implicitCast, valueType);
-          valueType = setterType;
-        }
-        node.interfaceTarget = interfaceTarget;
-      }
-    }
-    receiverType = _narrowInstanceReceiver(interfaceTarget, receiverType);
-    if (interfaceTarget != null) {
-      handleInstanceSet(node, receiverType, node.interfaceTarget, valueType);
-    } else {
-      handleDynamicSet(node, receiverType, node.name, valueType);
-    }
-    return valueType;
-  }
-
-  @override
   ir.DartType visitDynamicSet(ir.DynamicSet node) {
     ir.DartType receiverType = visitNode(node.receiver);
     ir.DartType valueType = visitNode(node.value);
@@ -911,69 +840,6 @@
   }
 
   @override
-  ir.DartType visitMethodInvocation(ir.MethodInvocation node) {
-    ArgumentTypes argumentTypes = _visitArguments(node.arguments);
-    ir.DartType receiverType = visitNode(node.receiver);
-    ir.Member interfaceTarget = node.interfaceTarget ??
-        _resolveDynamicInvocationTarget(
-            receiverType, node.name, node.arguments);
-    ir.DartType returnType;
-    if (interfaceTarget != null) {
-      ir.DartType functionType = _computeInstanceInvocationType(
-          receiverType, interfaceTarget, node.arguments, argumentTypes);
-      if (node.interfaceTarget == null) {
-        // We change [node] from being a dynamic invocation to an instance
-        // invocation, so we need to add static type checks to the arguments to
-        // match instance invocations created by the CFE.
-        // TODO(johnniwinther): Handle incremental target improvement.
-        _updateMethodInvocationTarget(node, argumentTypes, functionType);
-        node.interfaceTarget = interfaceTarget;
-      }
-      returnType = _getFunctionReturnType(functionType);
-    } else {
-      returnType = _computeDynamicInvocationReturnType(node, receiverType);
-    }
-    receiverType = _narrowInstanceReceiver(node.interfaceTarget, receiverType);
-    if (node.name.text == '==') {
-      TypeMap afterInvocation = typeMap;
-      ir.Expression left = node.receiver;
-      ir.Expression right = node.arguments.positional[0];
-      if (isNullLiteral(right)) {
-        _registerEqualsNull(afterInvocation, left);
-      }
-      if (isNullLiteral(left)) {
-        _registerEqualsNull(afterInvocation, right);
-      }
-      assert(node.interfaceTarget != null);
-      handleEqualsCall(left, receiverType, right, argumentTypes.positional[0],
-          node.interfaceTarget);
-    } else if (node.interfaceTarget != null) {
-      handleInstanceInvocation(
-          node, receiverType, interfaceTarget, argumentTypes);
-    } else {
-      ir.Expression receiver = node.receiver;
-      if (receiver is ir.VariableGet &&
-          receiver.variable.isFinal &&
-          receiver.variable.parent is ir.FunctionDeclaration) {
-        handleLocalFunctionInvocation(
-            node, receiver.variable.parent, argumentTypes, returnType);
-      } else {
-        handleDynamicInvocation(node, receiverType, argumentTypes, returnType);
-        // TODO(johnniwinther): Avoid treating a known function call as a
-        // dynamic call when CFE provides a way to distinguish the two.
-        if (operatorFromString(node.name.text) == null &&
-            receiverType is ir.DynamicType) {
-          // We might implicitly call a getter that returns a function.
-          handleFunctionInvocation(
-              node, const ir.DynamicType(), argumentTypes, returnType);
-        }
-      }
-    }
-    _staticTypeCache._expressionTypes[node] = returnType;
-    return returnType;
-  }
-
-  @override
   ir.DartType visitInstanceInvocation(ir.InstanceInvocation node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     ir.DartType receiverType = visitNode(node.receiver);
@@ -1060,9 +926,6 @@
       receiverType = _narrowInstanceReceiver(interfaceTarget, receiverType);
       handleInstanceInvocation(
           replacement, receiverType, interfaceTarget, argumentTypes);
-      if (replacement is ir.MethodInvocation) {
-        _staticTypeCache._expressionTypes[replacement] = resultType;
-      }
       return resultType;
     } else if (node.name == ir.Name.callName &&
         (receiverType is ir.FunctionType ||
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index 315ee23..05a45ee1 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -157,11 +157,6 @@
   }
 
   @override
-  ir.DartType visitPropertySet(ir.PropertySet node) {
-    return visitNode(node.value);
-  }
-
-  @override
   ThisInterfaceType visitThisExpression(ir.ThisExpression node) => thisType;
 
   @override
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index eab6a08..5c5021f 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -119,18 +119,7 @@
     if (node.variable.name == null &&
         node.variable.isFinal &&
         body is ir.ConditionalExpression) {
-      if (body.condition is ir.MethodInvocation && isNullLiteral(body.then)) {
-        ir.MethodInvocation invocation = body.condition;
-        ir.Expression receiver = invocation.receiver;
-        if (invocation.name.text == '==' &&
-            receiver is ir.VariableGet &&
-            receiver.variable == node.variable &&
-            isNullLiteral(invocation.arguments.positional.single)) {
-          // We have
-          //   let #t1 = e0 in #t1 == null ? null : e1
-          return new NullAwareExpression(node.variable, body.otherwise);
-        }
-      } else if (body.condition is ir.EqualsNull) {
+      if (body.condition is ir.EqualsNull) {
         ir.EqualsNull equalsNull = body.condition;
         ir.Expression receiver = equalsNull.expression;
         if (receiver is ir.VariableGet && receiver.variable == node.variable) {
@@ -161,12 +150,10 @@
   //
   //   (let _ = check(prefix) in prefix::field).property
   if (node is ir.StaticGet || node is ir.ConstantExpression) {
-    while (parent is ir.PropertyGet ||
-        parent is ir.InstanceGet ||
+    while (parent is ir.InstanceGet ||
         parent is ir.DynamicGet ||
         parent is ir.InstanceTearOff ||
         parent is ir.FunctionTearOff ||
-        parent is ir.MethodInvocation ||
         parent is ir.InstanceInvocation ||
         parent is ir.InstanceGetterInvocation ||
         parent is ir.DynamicInvocation ||
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index a1c35bf..33024bc 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1245,9 +1245,6 @@
     // TODO(efortuna): This is screaming for a common interface between
     // PropertyGet and SuperPropertyGet (and same for *Get). Talk to kernel
     // folks.
-    if (node is ir.PropertyGet) {
-      return getGetterSelector(node.name);
-    }
     if (node is ir.InstanceGet) {
       return getGetterSelector(node.name);
     }
@@ -1263,9 +1260,6 @@
     if (node is ir.SuperPropertyGet) {
       return getGetterSelector(node.name);
     }
-    if (node is ir.PropertySet) {
-      return getSetterSelector(node.name);
-    }
     if (node is ir.InstanceSet) {
       return getSetterSelector(node.name);
     }
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 5859d8e..74ad9f6 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -105,9 +105,6 @@
   bool get supportsExplicitGetterCalls => false;
 
   @override
-  bool get supportsNewMethodInvocationEncoding => true;
-
-  @override
   int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.none;
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/node_indexer.dart b/pkg/compiler/lib/src/serialization/node_indexer.dart
index 782e2fc..1e52a8f 100644
--- a/pkg/compiler/lib/src/serialization/node_indexer.dart
+++ b/pkg/compiler/lib/src/serialization/node_indexer.dart
@@ -106,12 +106,6 @@
   }
 
   @override
-  void visitPropertyGet(ir.PropertyGet node) {
-    registerNode(node);
-    super.visitPropertyGet(node);
-  }
-
-  @override
   void visitInstanceGet(ir.InstanceGet node) {
     registerNode(node);
     super.visitInstanceGet(node);
@@ -136,12 +130,6 @@
   }
 
   @override
-  void visitPropertySet(ir.PropertySet node) {
-    registerNode(node);
-    super.visitPropertySet(node);
-  }
-
-  @override
   void visitInstanceSet(ir.InstanceSet node) {
     registerNode(node);
     super.visitInstanceSet(node);
@@ -154,12 +142,6 @@
   }
 
   @override
-  void visitMethodInvocation(ir.MethodInvocation node) {
-    registerNode(node);
-    super.visitMethodInvocation(node);
-  }
-
-  @override
   void visitInstanceInvocation(ir.InstanceInvocation node) {
     registerNode(node);
     super.visitInstanceInvocation(node);
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ad0375f..643baf7 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3467,11 +3467,6 @@
   }
 
   @override
-  void visitPropertyGet(ir.PropertyGet node) {
-    _handlePropertyGet(node, node.receiver, node.name);
-  }
-
-  @override
   void visitVariableGet(ir.VariableGet node) {
     ir.VariableDeclaration variable = node.variable;
     HInstruction letBinding = _letBindings[variable];
@@ -3516,11 +3511,6 @@
   }
 
   @override
-  void visitPropertySet(ir.PropertySet node) {
-    _handlePropertySet(node, node.receiver, node.name, node.value);
-  }
-
-  @override
   void visitSuperPropertySet(ir.SuperPropertySet node) {
     SourceInformation sourceInformation =
         _sourceInformationBuilder.buildAssignment(node);
@@ -5032,10 +5022,7 @@
           isIntercepted: isIntercepted);
     }
     invoke.instructionContext = _currentFrame.member;
-    if (node is ir.MethodInvocation) {
-      invoke.isInvariant = node.isInvariant;
-      invoke.isBoundsSafe = node.isBoundsSafe;
-    } else if (node is ir.InstanceInvocation) {
+    if (node is ir.InstanceInvocation) {
       invoke.isInvariant = node.isInvariant;
       invoke.isBoundsSafe = node.isBoundsSafe;
     }
@@ -5274,11 +5261,6 @@
         _sourceInformationBuilder.buildCall(node, node));
   }
 
-  @override
-  void visitMethodInvocation(ir.MethodInvocation node) {
-    _handleMethodInvocation(node, node.receiver, node.arguments);
-  }
-
   void _handleEquals(ir.Expression node, ir.Expression left,
       HInstruction leftInstruction, HInstruction rightInstruction) {
     _pushDynamicInvocation(
@@ -7229,15 +7211,6 @@
   }
 
   @override
-  visitPropertyGet(ir.PropertyGet node) {
-    registerCall();
-    registerRegularNode();
-    registerReductiveNode();
-    skipReductiveNodes(() => visit(node.name));
-    visit(node.receiver);
-  }
-
-  @override
   visitInstanceGet(ir.InstanceGet node) {
     registerCall();
     registerRegularNode();
@@ -7265,16 +7238,6 @@
   }
 
   @override
-  visitPropertySet(ir.PropertySet node) {
-    registerCall();
-    registerRegularNode();
-    registerReductiveNode();
-    skipReductiveNodes(() => visit(node.name));
-    visit(node.receiver);
-    visit(node.value);
-  }
-
-  @override
   visitInstanceSet(ir.InstanceSet node) {
     registerCall();
     registerRegularNode();
@@ -7343,16 +7306,6 @@
   }
 
   @override
-  visitMethodInvocation(ir.MethodInvocation node) {
-    registerRegularNode();
-    registerReductiveNode();
-    registerCall();
-    visit(node.receiver);
-    skipReductiveNodes(() => visit(node.name));
-    _processArguments(node.arguments, null);
-  }
-
-  @override
   visitInstanceInvocation(ir.InstanceInvocation node) {
     registerRegularNode();
     registerReductiveNode();
diff --git a/pkg/compiler/test/inference/inference_test_helper.dart b/pkg/compiler/test/inference/inference_test_helper.dart
index 33565b7..231a108 100644
--- a/pkg/compiler/test/inference/inference_test_helper.dart
+++ b/pkg/compiler/test/inference/inference_test_helper.dart
@@ -146,7 +146,7 @@
         node is ir.FunctionDeclaration) {
       ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
       return getMemberValue(info.callMethod);
-    } else if (node is ir.MethodInvocation ||
+    } else if (
         node is ir.InstanceInvocation ||
         node is ir.InstanceGetterInvocation ||
         node is ir.DynamicInvocation ||
@@ -154,13 +154,13 @@
         node is ir.EqualsNull ||
         node is ir.EqualsCall) {
       return getTypeMaskValue(result.typeOfReceiver(node));
-    } else if (node is ir.PropertyGet ||
+    } else if (
         node is ir.InstanceGet ||
         node is ir.DynamicGet ||
         node is ir.InstanceTearOff ||
         node is ir.FunctionTearOff) {
       return getTypeMaskValue(result.typeOfReceiver(node));
-    } else if (node is ir.PropertySet ||
+    } else if (
         node is ir.InstanceSet ||
         node is ir.DynamicSet) {
       return getTypeMaskValue(result.typeOfReceiver(node));
diff --git a/pkg/compiler/test/static_type/static_type_test.dart b/pkg/compiler/test/static_type/static_type_test.dart
index 15cf87d..0123144 100644
--- a/pkg/compiler/test/static_type/static_type_test.dart
+++ b/pkg/compiler/test/static_type/static_type_test.dart
@@ -86,9 +86,6 @@
   String computeNodeValue(Id id, ir.TreeNode node) {
     if (node is ir.VariableGet) {
       return typeToText(node.accept(staticTypeCache));
-    } else if (node is ir.MethodInvocation) {
-      return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
-          '${typeToText(node.accept(staticTypeCache))}';
     } else if (node is ir.InstanceInvocation) {
       return '[${typeToText(node.receiver.accept(staticTypeCache))}]->'
           '${typeToText(node.accept(staticTypeCache))}';
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 2c37a60..e1d06c4 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -4563,12 +4563,6 @@
   }
 
   @override
-  js_ast.Expression visitPropertyGet(PropertyGet node) {
-    return _emitPropertyGet(
-        node.receiver, node.interfaceTarget, node.name.text);
-  }
-
-  @override
   js_ast.Expression visitDynamicSet(DynamicSet node) {
     return _emitPropertySet(node.receiver, null, node.value, node.name.text);
   }
@@ -4579,12 +4573,6 @@
         node.receiver, node.interfaceTarget, node.value, node.name.text);
   }
 
-  @override
-  js_ast.Expression visitPropertySet(PropertySet node) {
-    return _emitPropertySet(
-        node.receiver, node.interfaceTarget, node.value, node.name.text);
-  }
-
   js_ast.Expression _emitPropertyGet(Expression receiver, Member member,
       [String memberName]) {
     memberName ??= member.name.text;
@@ -4759,12 +4747,6 @@
         negated: false);
   }
 
-  @override
-  js_ast.Expression visitMethodInvocation(MethodInvocation node) {
-    return _emitMethodCall(
-        node.receiver, node.interfaceTarget, node.arguments, node);
-  }
-
   js_ast.Expression _emitMethodCall(Expression receiver, Member target,
       Arguments arguments, InvocationExpression node) {
     var name = node.name.text;
@@ -5749,11 +5731,7 @@
   @override
   js_ast.Expression visitNot(Not node) {
     var operand = node.operand;
-    if (operand is MethodInvocation && operand.name.text == '==') {
-      return _emitEqualityOperator(operand.receiver, operand.interfaceTarget,
-          operand.arguments.positional[0],
-          negated: true);
-    } else if (operand is EqualsCall) {
+    if (operand is EqualsCall) {
       return _emitEqualityOperator(
           operand.left, operand.interfaceTarget, operand.right,
           negated: true);
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 0e4ae0e..166080a 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -191,9 +191,7 @@
 }
 
 Expression? getInvocationReceiver(InvocationExpression node) {
-  if (node is MethodInvocation) {
-    return node.receiver;
-  } else if (node is InstanceInvocation) {
+  if (node is InstanceInvocation) {
     return node.receiver;
   } else if (node is DynamicInvocation) {
     return node.receiver;
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index 07fa7d4..71aaed2 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -91,10 +91,6 @@
   bool visitVariableSet(VariableSet node) => isNullable(node.value);
 
   @override
-  bool visitPropertyGet(PropertyGet node) =>
-      _getterIsNullable(node.interfaceTarget, node);
-
-  @override
   bool visitInstanceGet(InstanceGet node) =>
       _getterIsNullable(node.interfaceTarget, node);
 
@@ -110,9 +106,6 @@
       _getterIsNullable(null, node);
 
   @override
-  bool visitPropertySet(PropertySet node) => isNullable(node.value);
-
-  @override
   bool visitInstanceSet(InstanceSet node) => isNullable(node.value);
 
   @override
@@ -136,10 +129,6 @@
   bool visitStaticSet(StaticSet node) => isNullable(node.value);
 
   @override
-  bool visitMethodInvocation(MethodInvocation node) => _invocationIsNullable(
-      node.interfaceTarget, node.name.text, node, node.receiver);
-
-  @override
   bool visitInstanceInvocation(InstanceInvocation node) =>
       _invocationIsNullable(
           node.interfaceTarget, node.name.text, node, node.receiver);
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 5bc10c1..1beb7d8 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -48,9 +48,6 @@
   bool get supportsExplicitGetterCalls => false;
 
   @override
-  bool get supportsNewMethodInvocationEncoding => true;
-
-  @override
   int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.none;
 
   @override
@@ -409,36 +406,18 @@
   }
 
   @override
-  void visitPropertyGet(PropertyGet node) {
-    _checkTearoff(node.interfaceTarget);
-    super.visitPropertyGet(node);
-  }
-
-  @override
   void visitInstanceGet(InstanceGet node) {
     _checkTearoff(node.interfaceTarget);
     super.visitInstanceGet(node);
   }
 
   @override
-  void visitPropertySet(PropertySet node) {
-    _checkTarget(node.receiver, node.interfaceTarget);
-    super.visitPropertySet(node);
-  }
-
-  @override
   void visitInstanceSet(InstanceSet node) {
     _checkTarget(node.receiver, node.interfaceTarget);
     super.visitInstanceSet(node);
   }
 
   @override
-  void visitMethodInvocation(MethodInvocation node) {
-    _checkTarget(node.receiver, node.interfaceTarget);
-    super.visitMethodInvocation(node);
-  }
-
-  @override
   void visitInstanceInvocation(InstanceInvocation node) {
     _checkTarget(node.receiver, node.interfaceTarget);
     super.visitInstanceInvocation(node);
diff --git a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
index cf307b8..d1a2a4e 100644
--- a/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
+++ b/pkg/front_end/lib/src/api_prototype/lowering_predicates.dart
@@ -280,22 +280,7 @@
             block.statements.first is ExpressionStatement) {
           ExpressionStatement firstStatement =
               block.statements.first as ExpressionStatement;
-          if (firstStatement.expression is PropertySet) {
-            // We have
-            //
-            //    get field {
-            //      if (!_#isSet#field) {
-            //        this._#field = <init>;
-            //        ...
-            //      }
-            //      return _#field;
-            //    }
-            //
-            // in case `<init>` is the initializer.
-            PropertySet propertySet = firstStatement.expression as PropertySet;
-            assert(propertySet.interfaceTarget == getLateFieldTarget(node));
-            return propertySet.value;
-          } else if (firstStatement.expression is InstanceSet) {
+          if (firstStatement.expression is InstanceSet) {
             // We have
             //
             //    get field {
@@ -368,15 +353,6 @@
             //
             // in which case there is no initializer.
             return null;
-          } else if (then is PropertySet) {
-            // We have
-            //
-            //    get field => let # = this._#field in <is-unset>
-            //        ? this._#field = <init> : #;
-            //
-            // in which case `<init>` is the initializer.
-            assert(then.interfaceTarget == getLateFieldTarget(node));
-            return then.value;
           } else if (then is InstanceSet) {
             // We have
             //
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
index a9a0b74..98e54de 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -21,7 +21,6 @@
         ListLiteral,
         Name,
         ProcedureKind,
-        PropertyGet,
         Reference,
         ReturnStatement,
         StaticGet,
@@ -462,15 +461,10 @@
     Field nameField = nameFieldBuilder.field;
     ProcedureBuilder toStringBuilder =
         firstMemberNamed("toString") as ProcedureBuilder;
-    if (libraryBuilder
-        .loader.target.backendTarget.supportsNewMethodInvocationEncoding) {
-      toStringBuilder.body = new ReturnStatement(new InstanceGet(
-          InstanceAccessKind.Instance, new ThisExpression(), nameField.name,
-          interfaceTarget: nameField, resultType: nameField.type));
-    } else {
-      toStringBuilder.body = new ReturnStatement(
-          new PropertyGet(new ThisExpression(), nameField.name, nameField));
-    }
+    toStringBuilder.body = new ReturnStatement(new InstanceGet(
+        InstanceAccessKind.Instance, new ThisExpression(), nameField.name,
+        interfaceTarget: nameField, resultType: nameField.type));
+
     List<Expression> values = <Expression>[];
     if (enumConstantInfos != null) {
       for (EnumConstantInfo? enumConstantInfo in enumConstantInfos!) {
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 1a7c9bc..eceff88 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -330,11 +330,7 @@
       internalProblem(
           messageInternalProblemAlreadyInitialized, charOffset, fileUri);
     }
-    _fieldEncoding.createBodies(
-        coreTypes,
-        initializer,
-        library
-            .loader.target.backendTarget.supportsNewMethodInvocationEncoding);
+    _fieldEncoding.createBodies(coreTypes, initializer);
   }
 
   @override
@@ -614,8 +610,7 @@
   ///
   /// This method is not called for fields in outlines unless their are constant
   /// or part of a const constructor.
-  void createBodies(CoreTypes coreTypes, Expression? initializer,
-      bool useNewMethodInvocationEncoding);
+  void createBodies(CoreTypes coreTypes, Expression? initializer);
 
   List<Initializer> createInitializer(int fileOffset, Expression value,
       {required bool isSynthetic});
@@ -725,8 +720,7 @@
   void completeSignature(CoreTypes coreTypes) {}
 
   @override
-  void createBodies(CoreTypes coreTypes, Expression? initializer,
-      bool useNewMethodInvocationEncoding) {
+  void createBodies(CoreTypes coreTypes, Expression? initializer) {
     if (initializer != null) {
       _field.initializer = initializer..parent = _field;
     }
@@ -962,8 +956,7 @@
   }
 
   @override
-  void createBodies(CoreTypes coreTypes, Expression? initializer,
-      bool useNewMethodInvocationEncoding) {
+  void createBodies(CoreTypes coreTypes, Expression? initializer) {
     assert(_type != null, "Type has not been computed for field $name.");
     if (isSetEncoding == late_lowering.IsSetEncoding.useSentinel) {
       _field.initializer = new StaticInvocation(coreTypes.createSentinelMethod,
@@ -980,15 +973,11 @@
         ..fileOffset = fileOffset
         ..parent = _lateIsSetField;
     }
-    _lateGetter.function.body = _createGetterBody(
-        coreTypes, name, initializer, useNewMethodInvocationEncoding)
+    _lateGetter.function.body = _createGetterBody(coreTypes, name, initializer)
       ..parent = _lateGetter.function;
     if (_lateSetter != null) {
       _lateSetter!.function.body = _createSetterBody(
-          coreTypes,
-          name,
-          _lateSetter!.function.positionalParameters.first,
-          useNewMethodInvocationEncoding)
+          coreTypes, name, _lateSetter!.function.positionalParameters.first)
         ..parent = _lateSetter!.function;
     }
   }
@@ -1015,62 +1004,48 @@
   /// expression that promotes the expression to [_type]. This is needed for a
   /// sound encoding of fields with type variable type of undetermined
   /// nullability.
-  Expression _createFieldRead(bool useNewMethodInvocationEncoding,
-      {bool needsPromotion: false}) {
+  Expression _createFieldRead({bool needsPromotion: false}) {
     assert(_type != null, "Type has not been computed for field $name.");
     if (needsPromotion) {
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          _createFieldGet(_field, useNewMethodInvocationEncoding),
+          _createFieldGet(_field),
           type: _type!.withDeclaredNullability(Nullability.nullable))
         ..fileOffset = fileOffset;
       return new Let(
           variable, new VariableGet(variable, _type)..fileOffset = fileOffset);
     } else {
-      return _createFieldGet(_field, useNewMethodInvocationEncoding);
+      return _createFieldGet(_field);
     }
   }
 
   /// Creates an [Expression] that reads [field].
-  Expression _createFieldGet(Field field, bool useNewMethodInvocationEncoding) {
+  Expression _createFieldGet(Field field) {
     if (field.isStatic) {
       return new StaticGet(field)..fileOffset = fileOffset;
     } else {
-      if (useNewMethodInvocationEncoding) {
-        // No substitution needed for the result type, since any type variables
-        // in there are also in scope at the access site.
-        return new InstanceGet(InstanceAccessKind.Instance,
-            new ThisExpression()..fileOffset = fileOffset, field.name,
-            interfaceTarget: field, resultType: field.type)
-          ..fileOffset = fileOffset;
-      } else {
-        return new PropertyGet(
-            new ThisExpression()..fileOffset = fileOffset, field.name, field)
-          ..fileOffset = fileOffset;
-      }
+      // No substitution needed for the result type, since any type variables
+      // in there are also in scope at the access site.
+      return new InstanceGet(InstanceAccessKind.Instance,
+          new ThisExpression()..fileOffset = fileOffset, field.name,
+          interfaceTarget: field, resultType: field.type)
+        ..fileOffset = fileOffset;
     }
   }
 
   /// Creates an [Expression] that writes [value] to [field].
-  Expression _createFieldSet(
-      Field field, Expression value, bool useNewMethodInvocationEncoding) {
+  Expression _createFieldSet(Field field, Expression value) {
     if (field.isStatic) {
       return new StaticSet(field, value)..fileOffset = fileOffset;
     } else {
-      if (useNewMethodInvocationEncoding) {
-        return new InstanceSet(InstanceAccessKind.Instance,
-            new ThisExpression()..fileOffset = fileOffset, field.name, value,
-            interfaceTarget: field)
-          ..fileOffset = fileOffset;
-      } else {
-        return new PropertySet(new ThisExpression()..fileOffset = fileOffset,
-            field.name, value, field)
-          ..fileOffset = fileOffset;
-      }
+      return new InstanceSet(InstanceAccessKind.Instance,
+          new ThisExpression()..fileOffset = fileOffset, field.name, value,
+          interfaceTarget: field)
+        ..fileOffset = fileOffset;
     }
   }
 
-  Statement _createGetterBody(CoreTypes coreTypes, String name,
-      Expression? initializer, bool useNewMethodInvocationEncoding);
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer);
 
   Procedure? _createSetter(
       Name name, Uri fileUri, int charOffset, Reference? reference,
@@ -1094,8 +1069,8 @@
       ..isNonNullableByDefault = true;
   }
 
-  Statement _createSetterBody(CoreTypes coreTypes, String name,
-      VariableDeclaration parameter, bool useNewMethodInvocationEncoding);
+  Statement _createSetterBody(
+      CoreTypes coreTypes, String name, VariableDeclaration parameter);
 
   @override
   DartType get type {
@@ -1255,30 +1230,29 @@
 
 mixin NonFinalLate on AbstractLateFieldEncoding {
   @override
-  Statement _createSetterBody(CoreTypes coreTypes, String name,
-      VariableDeclaration parameter, bool useNewMethodInvocationEncoding) {
+  Statement _createSetterBody(
+      CoreTypes coreTypes, String name, VariableDeclaration parameter) {
     assert(_type != null, "Type has not been computed for field $name.");
     return late_lowering.createSetterBody(
         coreTypes, fileOffset, name, parameter, _type!,
         shouldReturnValue: false,
         createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value, useNewMethodInvocationEncoding),
-        createIsSetWrite: (Expression value) => _createFieldSet(
-            _lateIsSetField!, value, useNewMethodInvocationEncoding),
+            _createFieldSet(_field, value),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
         isSetEncoding: isSetEncoding);
   }
 }
 
 mixin LateWithoutInitializer on AbstractLateFieldEncoding {
   @override
-  Statement _createGetterBody(CoreTypes coreTypes, String name,
-      Expression? initializer, bool useNewMethodInvocationEncoding) {
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer) {
     assert(_type != null, "Type has not been computed for field $name.");
     return late_lowering.createGetterBodyWithoutInitializer(
-        coreTypes, fileOffset, name, type, useNewMethodInvocationEncoding,
+        coreTypes, fileOffset, name, type,
         createVariableRead: _createFieldRead,
-        createIsSetRead: () =>
-            _createFieldGet(_lateIsSetField!, useNewMethodInvocationEncoding),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
         isSetEncoding: isSetEncoding,
         forField: true);
   }
@@ -1348,18 +1322,17 @@
             isSetStrategy);
 
   @override
-  Statement _createGetterBody(CoreTypes coreTypes, String name,
-      Expression? initializer, bool useNewMethodInvocationEncoding) {
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer) {
     assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createGetterWithInitializer(coreTypes, fileOffset,
-        name, _type!, initializer!, useNewMethodInvocationEncoding,
+    return late_lowering.createGetterWithInitializer(
+        coreTypes, fileOffset, name, _type!, initializer!,
         createVariableRead: _createFieldRead,
         createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value, useNewMethodInvocationEncoding),
-        createIsSetRead: () =>
-            _createFieldGet(_lateIsSetField!, useNewMethodInvocationEncoding),
-        createIsSetWrite: (Expression value) => _createFieldSet(
-            _lateIsSetField!, value, useNewMethodInvocationEncoding),
+            _createFieldSet(_field, value),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
         isSetEncoding: isSetEncoding);
   }
 }
@@ -1396,20 +1369,18 @@
             isSetStrategy);
 
   @override
-  Statement _createSetterBody(CoreTypes coreTypes, String name,
-      VariableDeclaration parameter, bool useNewMethodInvocationEncoding) {
+  Statement _createSetterBody(
+      CoreTypes coreTypes, String name, VariableDeclaration parameter) {
     assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createSetterBodyFinal(coreTypes, fileOffset, name,
-        parameter, type, useNewMethodInvocationEncoding,
+    return late_lowering.createSetterBodyFinal(
+        coreTypes, fileOffset, name, parameter, type,
         shouldReturnValue: false,
-        createVariableRead: (bool useNewMethodInvocationEncoding) =>
-            _createFieldGet(_field, useNewMethodInvocationEncoding),
+        createVariableRead: () => _createFieldGet(_field),
         createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value, useNewMethodInvocationEncoding),
-        createIsSetRead: () =>
-            _createFieldGet(_lateIsSetField!, useNewMethodInvocationEncoding),
-        createIsSetWrite: (Expression value) => _createFieldSet(
-            _lateIsSetField!, value, useNewMethodInvocationEncoding),
+            _createFieldSet(_field, value),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
         isSetEncoding: isSetEncoding,
         forField: true);
   }
@@ -1445,18 +1416,17 @@
             isCovariant,
             isSetStrategy);
   @override
-  Statement _createGetterBody(CoreTypes coreTypes, String name,
-      Expression? initializer, bool useNewMethodInvocationEncoding) {
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer) {
     assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createGetterWithInitializerWithRecheck(coreTypes,
-        fileOffset, name, _type!, initializer!, useNewMethodInvocationEncoding,
+    return late_lowering.createGetterWithInitializerWithRecheck(
+        coreTypes, fileOffset, name, _type!, initializer!,
         createVariableRead: _createFieldRead,
         createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value, useNewMethodInvocationEncoding),
-        createIsSetRead: () =>
-            _createFieldGet(_lateIsSetField!, useNewMethodInvocationEncoding),
-        createIsSetWrite: (Expression value) => _createFieldSet(
-            _lateIsSetField!, value, useNewMethodInvocationEncoding),
+            _createFieldSet(_field, value),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
         isSetEncoding: isSetEncoding,
         forField: true);
   }
@@ -1468,8 +1438,8 @@
       null;
 
   @override
-  Statement _createSetterBody(CoreTypes coreTypes, String name,
-          VariableDeclaration parameter, bool useNewMethodInvocationEncoding) =>
+  Statement _createSetterBody(
+          CoreTypes coreTypes, String name, VariableDeclaration parameter) =>
       throw new UnsupportedError(
           '$runtimeType._createSetterBody is not supported.');
 }
@@ -1692,8 +1662,7 @@
   void completeSignature(CoreTypes coreTypes) {}
 
   @override
-  void createBodies(CoreTypes coreTypes, Expression? initializer,
-      bool useNewMethodInvocationEncoding) {
+  void createBodies(CoreTypes coreTypes, Expression? initializer) {
     //assert(initializer != null);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 211d929..0015f60 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1260,7 +1260,7 @@
       // environment.
       // For const functions, recompute getters instead of using the cached
       // value.
-      bool isGetter = node is InstanceGet || node is PropertyGet;
+      bool isGetter = node is InstanceGet;
       if (nodeCache.containsKey(node) && !(enableConstFunctions && isGetter)) {
         Constant? cachedResult = nodeCache[node];
         if (cachedResult == null) {
@@ -1283,7 +1283,7 @@
     } else {
       bool sentinelInserted = false;
       if (nodeCache.containsKey(node)) {
-        bool isRecursiveFunctionCall = node is MethodInvocation ||
+        bool isRecursiveFunctionCall =
             node is InstanceInvocation ||
             node is FunctionInvocation ||
             node is LocalFunctionInvocation ||
@@ -2486,52 +2486,6 @@
   }
 
   @override
-  Constant visitMethodInvocation(MethodInvocation node) {
-    // We have no support for generic method invocation at the moment.
-    if (node.arguments.types.isNotEmpty && !enableConstFunctions) {
-      return createInvalidExpressionConstant(node, "generic method invocation");
-    }
-
-    // We have no support for method invocation with named arguments at the
-    // moment.
-    if (node.arguments.named.isNotEmpty && !enableConstFunctions) {
-      return createInvalidExpressionConstant(
-          node, "method invocation with named arguments");
-    }
-
-    final Constant receiver = _evaluateSubexpression(node.receiver);
-    if (receiver is AbortConstant) return receiver;
-
-    final List<Constant>? positionalArguments =
-        _evaluatePositionalArguments(node.arguments);
-
-    if (positionalArguments == null) {
-      AbortConstant error = _gotError!;
-      _gotError = null;
-      return error;
-    }
-    assert(_gotError == null);
-    // ignore: unnecessary_null_comparison
-    assert(positionalArguments != null);
-
-    if (shouldBeUnevaluated) {
-      return unevaluated(
-          node,
-          new MethodInvocation(
-              extract(receiver),
-              node.name,
-              unevaluatedArguments(
-                  positionalArguments, {}, node.arguments.types),
-              node.interfaceTarget)
-            ..fileOffset = node.fileOffset
-            ..flags = node.flags);
-    }
-
-    return _handleInvocation(node, node.name, receiver, positionalArguments,
-        arguments: node.arguments);
-  }
-
-  @override
   Constant visitLogicalExpression(LogicalExpression node) {
     final Constant left = _evaluateSubexpression(node.left);
     if (left is AbortConstant) return left;
@@ -2760,87 +2714,6 @@
   }
 
   @override
-  Constant visitPropertyGet(PropertyGet node) {
-    if (node.receiver is ThisExpression) {
-      // Probably unreachable unless trying to evaluate non-const stuff as
-      // const.
-      // Access "this" during instance creation.
-      if (instanceBuilder == null) {
-        return createErrorConstant(node, messageNotAConstantExpression);
-      }
-
-      for (final MapEntry<Field, Constant> entry
-          in instanceBuilder!.fields.entries) {
-        final Field field = entry.key;
-        if (field.name == node.name) {
-          return entry.value;
-        }
-      }
-
-      // Meant as a "stable backstop for situations where Fasta fails to
-      // rewrite various erroneous constructs into invalid expressions".
-      // Probably unreachable.
-      return createInvalidExpressionConstant(node,
-          'Could not evaluate field get ${node.name} on incomplete instance');
-    }
-
-    final Constant receiver = _evaluateSubexpression(node.receiver);
-    if (receiver is AbortConstant) return receiver;
-    if (receiver is StringConstant && node.name.text == 'length') {
-      return canonicalize(intFolder.makeIntConstant(receiver.value.length));
-    } else if (shouldBeUnevaluated) {
-      return unevaluated(node,
-          new PropertyGet(extract(receiver), node.name, node.interfaceTarget));
-    } else if (receiver is NullConstant) {
-      return createErrorConstant(node, messageConstEvalNullValue);
-    } else if (receiver is ListConstant && enableConstFunctions) {
-      switch (node.name.text) {
-        case 'first':
-          if (receiver.entries.isEmpty) {
-            return new _AbortDueToThrowConstant(
-                node, new StateError('No element'));
-          }
-          return receiver.entries.first;
-        case 'isEmpty':
-          return new BoolConstant(receiver.entries.isEmpty);
-        case 'isNotEmpty':
-          return new BoolConstant(receiver.entries.isNotEmpty);
-        // TODO(kallentu): case 'iterator'
-        case 'last':
-          if (receiver.entries.isEmpty) {
-            return new _AbortDueToThrowConstant(
-                node, new StateError('No element'));
-          }
-          return receiver.entries.last;
-        case 'length':
-          return new IntConstant(receiver.entries.length);
-        // TODO(kallentu): case 'reversed'
-        case 'single':
-          if (receiver.entries.isEmpty) {
-            return new _AbortDueToThrowConstant(
-                node, new StateError('No element'));
-          } else if (receiver.entries.length > 1) {
-            return new _AbortDueToThrowConstant(
-                node, new StateError('Too many elements'));
-          }
-          return receiver.entries.single;
-      }
-    } else if (receiver is InstanceConstant && enableConstFunctions) {
-      for (final MapEntry<Reference, Constant> entry
-          in receiver.fieldValues.entries) {
-        final Field field = entry.key.asField;
-        if (field.name == node.name) {
-          return entry.value;
-        }
-      }
-    }
-    return createErrorConstant(
-        node,
-        templateConstEvalInvalidPropertyGet.withArguments(
-            node.name.text, receiver, isNonNullableByDefault));
-  }
-
-  @override
   Constant visitLet(Let node) {
     Constant value = _evaluateSubexpression(node.variable.initializer!);
     if (value is AbortConstant) return value;
@@ -3793,9 +3666,6 @@
   Constant visitLoadLibrary(LoadLibrary node) => defaultExpression(node);
 
   @override
-  Constant visitPropertySet(PropertySet node) => defaultExpression(node);
-
-  @override
   Constant visitRethrow(Rethrow node) => defaultExpression(node);
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 719356e..7be2835 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1110,8 +1110,6 @@
       Expression? syntheticAssignment, bool hasProblem) {
     if (syntheticAssignment is VariableSet) {
       return new LocalForInVariable(syntheticAssignment);
-    } else if (syntheticAssignment is PropertySet) {
-      return new PropertyForInVariable(syntheticAssignment);
     } else if (syntheticAssignment is InternalPropertySet) {
       return new InternalPropertyForInVariable(syntheticAssignment);
     } else if (syntheticAssignment is SuperPropertySet) {
@@ -2808,20 +2806,6 @@
     return new ExpressionInferenceResult(inferredType, node);
   }
 
-  @override
-  ExpressionInferenceResult visitMethodInvocation(
-      MethodInvocation node, DartType typeContext) {
-    assert(node.name != unaryMinusName);
-    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
-        node.receiver, const UnknownType(), true);
-    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
-    Expression receiver = result.nullAwareAction;
-    DartType receiverType = result.nullAwareActionType;
-    return inferrer.inferMethodInvocation(node.fileOffset, nullAwareGuards,
-        receiver, receiverType, node.name, node.arguments, typeContext,
-        isExpressionInvocation: false, isImplicitCall: false);
-  }
-
   ExpressionInferenceResult visitInternalMethodInvocation(
       InternalMethodInvocation node, DartType typeContext) {
     assert(node.name != unaryMinusName);
@@ -4041,24 +4025,20 @@
         right, const UnknownType(), typeNeeded,
         isVoidAllowed: false);
 
-    if (inferrer.useNewMethodInvocationEncoding) {
-      if (_isNull(right)) {
-        equals = new EqualsNull(left)..fileOffset = fileOffset;
-      } else if (_isNull(left)) {
-        equals = new EqualsNull(rightResult.expression)
-          ..fileOffset = fileOffset;
+    if (_isNull(right)) {
+      equals = new EqualsNull(left)..fileOffset = fileOffset;
+    } else if (_isNull(left)) {
+      equals = new EqualsNull(rightResult.expression)..fileOffset = fileOffset;
+    }
+    if (equals != null) {
+      if (isNot) {
+        equals = new Not(equals)..fileOffset = fileOffset;
       }
-      if (equals != null) {
-        if (isNot) {
-          equals = new Not(equals)..fileOffset = fileOffset;
-        }
-        inferrer.flowAnalysis.equalityOp_end(
-            equals, rightResult.expression, rightResult.inferredType,
-            notEqual: isNot);
-        return new ExpressionInferenceResult(
-            inferrer.coreTypes.boolRawType(inferrer.library.nonNullable),
-            equals);
-      }
+      inferrer.flowAnalysis.equalityOp_end(
+          equals, rightResult.expression, rightResult.inferredType,
+          notEqual: isNot);
+      return new ExpressionInferenceResult(
+          inferrer.coreTypes.boolRawType(inferrer.library.nonNullable), equals);
     }
 
     ObjectAccessTarget equalsTarget = inferrer.findInterfaceMember(
@@ -4092,47 +4072,33 @@
         nullabilityNullTypeErrorTemplate:
             templateArgumentTypeNotAssignableNullabilityNullType);
 
-    if (inferrer.useNewMethodInvocationEncoding) {
-      if (equalsTarget.isInstanceMember || equalsTarget.isObjectMember) {
-        FunctionType functionType =
-            inferrer.getFunctionType(equalsTarget, leftType);
-        equals = new EqualsCall(left, right,
-            functionType: functionType,
-            interfaceTarget: equalsTarget.member as Procedure)
-          ..fileOffset = fileOffset;
-        if (isNot) {
-          equals = new Not(equals)..fileOffset = fileOffset;
-        }
-      } else {
-        assert(equalsTarget.isNever);
-        FunctionType functionType = new FunctionType([const DynamicType()],
-            const NeverType.nonNullable(), inferrer.library.nonNullable);
-        // Ensure operator == member even for `Never`.
-        Member target = inferrer
-            .findInterfaceMember(const DynamicType(), equalsName, -1,
-                instrumented: false)
-            .member!;
-        equals = new EqualsCall(left, right,
-            functionType: functionType, interfaceTarget: target as Procedure)
-          ..fileOffset = fileOffset;
-        if (isNot) {
-          equals = new Not(equals)..fileOffset = fileOffset;
-        }
+    if (equalsTarget.isInstanceMember || equalsTarget.isObjectMember) {
+      FunctionType functionType =
+          inferrer.getFunctionType(equalsTarget, leftType);
+      equals = new EqualsCall(left, right,
+          functionType: functionType,
+          interfaceTarget: equalsTarget.member as Procedure)
+        ..fileOffset = fileOffset;
+      if (isNot) {
+        equals = new Not(equals)..fileOffset = fileOffset;
       }
     } else {
-      equals = new MethodInvocation(
-          left,
-          equalsName,
-          new Arguments(<Expression>[
-            right,
-          ])
-            ..fileOffset = fileOffset,
-          equalsTarget.member)
+      assert(equalsTarget.isNever);
+      FunctionType functionType = new FunctionType([const DynamicType()],
+          const NeverType.nonNullable(), inferrer.library.nonNullable);
+      // Ensure operator == member even for `Never`.
+      Member target = inferrer
+          .findInterfaceMember(const DynamicType(), equalsName, -1,
+              instrumented: false)
+          .member!;
+      equals = new EqualsCall(left, right,
+          functionType: functionType, interfaceTarget: target as Procedure)
         ..fileOffset = fileOffset;
       if (isNot) {
         equals = new Not(equals)..fileOffset = fileOffset;
       }
     }
+
     inferrer.flowAnalysis.equalityOp_end(
         equals, right, rightResult.inferredType,
         notEqual: isNot);
@@ -4233,75 +4199,39 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.invalid:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          binary = new DynamicInvocation(
-              DynamicAccessKind.Invalid,
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          binary = new MethodInvocation(
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset,
-              binaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        binary = new DynamicInvocation(
+            DynamicAccessKind.Invalid,
+            left,
+            binaryName,
+            new Arguments(<Expression>[
+              right,
+            ])
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.callFunction:
       case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          binary = new DynamicInvocation(
-              DynamicAccessKind.Dynamic,
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          binary = new MethodInvocation(
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset,
-              binaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        binary = new DynamicInvocation(
+            DynamicAccessKind.Dynamic,
+            left,
+            binaryName,
+            new Arguments(<Expression>[
+              right,
+            ])
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.never:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          binary = new DynamicInvocation(
-              DynamicAccessKind.Never,
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          binary = new MethodInvocation(
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset,
-              binaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        binary = new DynamicInvocation(
+            DynamicAccessKind.Never,
+            left,
+            binaryName,
+            new Arguments(<Expression>[
+              right,
+            ])
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
       case ObjectAccessTargetKind.objectMember:
@@ -4316,30 +4246,18 @@
               new InstrumentationValueForMember(binaryTarget.member!));
         }
 
-        if (inferrer.useNewMethodInvocationEncoding) {
-          binary = new InstanceInvocation(
-              InstanceAccessKind.Instance,
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset,
-              functionType: new FunctionType(
-                  [rightType], binaryType, inferrer.library.nonNullable),
-              interfaceTarget: binaryTarget.member as Procedure)
-            ..fileOffset = fileOffset;
-        } else {
-          binary = new MethodInvocation(
-              left,
-              binaryName,
-              new Arguments(<Expression>[
-                right,
-              ])
-                ..fileOffset = fileOffset,
-              binaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        binary = new InstanceInvocation(
+            InstanceAccessKind.Instance,
+            left,
+            binaryName,
+            new Arguments(<Expression>[
+              right,
+            ])
+              ..fileOffset = fileOffset,
+            functionType: new FunctionType(
+                [rightType], binaryType, inferrer.library.nonNullable),
+            interfaceTarget: binaryTarget.member as Procedure)
+          ..fileOffset = fileOffset;
 
         if (binaryCheckKind ==
             MethodContravarianceCheckKind.checkMethodReturn) {
@@ -4421,48 +4339,21 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.invalid:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          unary = new DynamicInvocation(DynamicAccessKind.Invalid, expression,
-              unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          unary = new MethodInvocation(
-              expression,
-              unaryName,
-              new Arguments(<Expression>[])..fileOffset = fileOffset,
-              unaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        unary = new DynamicInvocation(DynamicAccessKind.Invalid, expression,
+            unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.never:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          unary = new DynamicInvocation(DynamicAccessKind.Never, expression,
-              unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          unary = new MethodInvocation(
-              expression,
-              unaryName,
-              new Arguments(<Expression>[])..fileOffset = fileOffset,
-              unaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        unary = new DynamicInvocation(DynamicAccessKind.Never, expression,
+            unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.callFunction:
       case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          unary = new DynamicInvocation(DynamicAccessKind.Dynamic, expression,
-              unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          unary = new MethodInvocation(
-              expression,
-              unaryName,
-              new Arguments(<Expression>[])..fileOffset = fileOffset,
-              unaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        unary = new DynamicInvocation(DynamicAccessKind.Dynamic, expression,
+            unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
       case ObjectAccessTargetKind.objectMember:
@@ -4477,24 +4368,12 @@
               new InstrumentationValueForMember(unaryTarget.member!));
         }
 
-        if (inferrer.useNewMethodInvocationEncoding) {
-          unary = new InstanceInvocation(
-              InstanceAccessKind.Instance,
-              expression,
-              unaryName,
-              new Arguments(<Expression>[])..fileOffset = fileOffset,
-              functionType: new FunctionType(
-                  <DartType>[], unaryType, inferrer.library.nonNullable),
-              interfaceTarget: unaryTarget.member as Procedure)
-            ..fileOffset = fileOffset;
-        } else {
-          unary = new MethodInvocation(
-              expression,
-              unaryName,
-              new Arguments(<Expression>[])..fileOffset = fileOffset,
-              unaryTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        unary = new InstanceInvocation(InstanceAccessKind.Instance, expression,
+            unaryName, new Arguments(<Expression>[])..fileOffset = fileOffset,
+            functionType: new FunctionType(
+                <DartType>[], unaryType, inferrer.library.nonNullable),
+            interfaceTarget: unaryTarget.member as Procedure)
+          ..fileOffset = fileOffset;
 
         if (unaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
           if (inferrer.instrumentation != null) {
@@ -4573,117 +4452,69 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.invalid:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read = new DynamicInvocation(
-              DynamicAccessKind.Invalid,
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          read = new MethodInvocation(
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset,
-              readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new DynamicInvocation(
+            DynamicAccessKind.Invalid,
+            readReceiver,
+            indexGetName,
+            new Arguments(<Expression>[
+              readIndex,
+            ])
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.never:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read = new DynamicInvocation(
-              DynamicAccessKind.Never,
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          read = new MethodInvocation(
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset,
-              readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new DynamicInvocation(
+            DynamicAccessKind.Never,
+            readReceiver,
+            indexGetName,
+            new Arguments(<Expression>[
+              readIndex,
+            ])
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.callFunction:
       case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read = new DynamicInvocation(
-              DynamicAccessKind.Dynamic,
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          read = new MethodInvocation(
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset,
-              readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new DynamicInvocation(
+            DynamicAccessKind.Dynamic,
+            readReceiver,
+            indexGetName,
+            new Arguments(<Expression>[
+              readIndex,
+            ])
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
       case ObjectAccessTargetKind.objectMember:
       case ObjectAccessTargetKind.nullableInstanceMember:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          InstanceAccessKind kind;
-          switch (readTarget.kind) {
-            case ObjectAccessTargetKind.instanceMember:
-              kind = InstanceAccessKind.Instance;
-              break;
-            case ObjectAccessTargetKind.nullableInstanceMember:
-              kind = InstanceAccessKind.Nullable;
-              break;
-            case ObjectAccessTargetKind.objectMember:
-              kind = InstanceAccessKind.Object;
-              break;
-            default:
-              throw new UnsupportedError('Unexpected target kind $readTarget');
-          }
-          read = new InstanceInvocation(
-              kind,
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset,
-              functionType: new FunctionType(
-                  [indexType], readType, inferrer.library.nonNullable),
-              interfaceTarget: readTarget.member as Procedure)
-            ..fileOffset = fileOffset;
-        } else {
-          read = new MethodInvocation(
-              readReceiver,
-              indexGetName,
-              new Arguments(<Expression>[
-                readIndex,
-              ])
-                ..fileOffset = fileOffset,
-              readTarget.member)
-            ..fileOffset = fileOffset;
+        InstanceAccessKind kind;
+        switch (readTarget.kind) {
+          case ObjectAccessTargetKind.instanceMember:
+            kind = InstanceAccessKind.Instance;
+            break;
+          case ObjectAccessTargetKind.nullableInstanceMember:
+            kind = InstanceAccessKind.Nullable;
+            break;
+          case ObjectAccessTargetKind.objectMember:
+            kind = InstanceAccessKind.Object;
+            break;
+          default:
+            throw new UnsupportedError('Unexpected target kind $readTarget');
         }
+        read = new InstanceInvocation(
+            kind,
+            readReceiver,
+            indexGetName,
+            new Arguments(<Expression>[
+              readIndex,
+            ])
+              ..fileOffset = fileOffset,
+            functionType: new FunctionType(
+                [indexType], readType, inferrer.library.nonNullable),
+            interfaceTarget: readTarget.member as Procedure)
+          ..fileOffset = fileOffset;
         if (readCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
           if (inferrer.instrumentation != null) {
             inferrer.instrumentation!.record(
@@ -4756,102 +4587,54 @@
           ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.invalid:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          write = new DynamicInvocation(
-              DynamicAccessKind.Invalid,
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          write = new MethodInvocation(
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset,
-              writeTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        write = new DynamicInvocation(
+            DynamicAccessKind.Invalid,
+            receiver,
+            indexSetName,
+            new Arguments(<Expression>[index, value])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.never:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          write = new DynamicInvocation(
-              DynamicAccessKind.Never,
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-        } else {
-          write = new MethodInvocation(
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset,
-              writeTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        write = new DynamicInvocation(
+            DynamicAccessKind.Never,
+            receiver,
+            indexSetName,
+            new Arguments(<Expression>[index, value])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.callFunction:
       case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          write = new DynamicInvocation(
-              DynamicAccessKind.Dynamic,
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset)
-            ..fileOffset = fileOffset;
-          break;
-        } else {
-          write = new MethodInvocation(
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset,
-              writeTarget.member)
-            ..fileOffset = fileOffset;
-          break;
-        }
+        write = new DynamicInvocation(
+            DynamicAccessKind.Dynamic,
+            receiver,
+            indexSetName,
+            new Arguments(<Expression>[index, value])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
+        break;
       case ObjectAccessTargetKind.instanceMember:
       case ObjectAccessTargetKind.objectMember:
       case ObjectAccessTargetKind.nullableInstanceMember:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          InstanceAccessKind kind;
-          switch (writeTarget.kind) {
-            case ObjectAccessTargetKind.instanceMember:
-              kind = InstanceAccessKind.Instance;
-              break;
-            case ObjectAccessTargetKind.nullableInstanceMember:
-              kind = InstanceAccessKind.Nullable;
-              break;
-            case ObjectAccessTargetKind.objectMember:
-              kind = InstanceAccessKind.Object;
-              break;
-            default:
-              throw new UnsupportedError('Unexpected target kind $writeTarget');
-          }
-          write = new InstanceInvocation(
-              kind,
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset,
-              functionType: new FunctionType([indexType, valueType],
-                  const VoidType(), inferrer.library.nonNullable),
-              interfaceTarget: writeTarget.member as Procedure)
-            ..fileOffset = fileOffset;
-        } else {
-          write = new MethodInvocation(
-              receiver,
-              indexSetName,
-              new Arguments(<Expression>[index, value])
-                ..fileOffset = fileOffset,
-              writeTarget.member)
-            ..fileOffset = fileOffset;
+        InstanceAccessKind kind;
+        switch (writeTarget.kind) {
+          case ObjectAccessTargetKind.instanceMember:
+            kind = InstanceAccessKind.Instance;
+            break;
+          case ObjectAccessTargetKind.nullableInstanceMember:
+            kind = InstanceAccessKind.Nullable;
+            break;
+          case ObjectAccessTargetKind.objectMember:
+            kind = InstanceAccessKind.Object;
+            break;
+          default:
+            throw new UnsupportedError('Unexpected target kind $writeTarget');
         }
+        write = new InstanceInvocation(kind, receiver, indexSetName,
+            new Arguments(<Expression>[index, value])..fileOffset = fileOffset,
+            functionType: new FunctionType([indexType, valueType],
+                const VoidType(), inferrer.library.nonNullable),
+            interfaceTarget: writeTarget.member as Procedure)
+          ..fileOffset = fileOffset;
         break;
     }
     if (!inferrer.isTopLevel && writeTarget.isNullable) {
@@ -4931,42 +4714,20 @@
         }
         break;
       case ObjectAccessTargetKind.never:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read = new DynamicGet(DynamicAccessKind.Never, receiver, propertyName)
-            ..fileOffset = fileOffset;
-        } else {
-          read = new PropertyGet(receiver, propertyName, readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new DynamicGet(DynamicAccessKind.Never, receiver, propertyName)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.dynamic:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read =
-              new DynamicGet(DynamicAccessKind.Dynamic, receiver, propertyName)
-                ..fileOffset = fileOffset;
-        } else {
-          read = new PropertyGet(receiver, propertyName, readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new DynamicGet(DynamicAccessKind.Dynamic, receiver, propertyName)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.invalid:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read =
-              new DynamicGet(DynamicAccessKind.Invalid, receiver, propertyName)
-                ..fileOffset = fileOffset;
-        } else {
-          read = new PropertyGet(receiver, propertyName, readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new DynamicGet(DynamicAccessKind.Invalid, receiver, propertyName)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.callFunction:
       case ObjectAccessTargetKind.nullableCallFunction:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          read = new FunctionTearOff(receiver)..fileOffset = fileOffset;
-        } else {
-          read = new PropertyGet(receiver, propertyName, readTarget.member)
-            ..fileOffset = fileOffset;
-        }
+        read = new FunctionTearOff(receiver)..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
       case ObjectAccessTargetKind.objectMember:
@@ -4978,32 +4739,28 @@
           inferrer.instrumentation!.record(inferrer.uriForInstrumentation,
               fileOffset, 'target', new InstrumentationValueForMember(member));
         }
-        if (inferrer.useNewMethodInvocationEncoding) {
-          InstanceAccessKind kind;
-          switch (readTarget.kind) {
-            case ObjectAccessTargetKind.instanceMember:
-              kind = InstanceAccessKind.Instance;
-              break;
-            case ObjectAccessTargetKind.nullableInstanceMember:
-              kind = InstanceAccessKind.Nullable;
-              break;
-            case ObjectAccessTargetKind.objectMember:
-              kind = InstanceAccessKind.Object;
-              break;
-            default:
-              throw new UnsupportedError('Unexpected target kind $readTarget');
-          }
-          if (member is Procedure && member.kind == ProcedureKind.Method) {
-            read = new InstanceTearOff(kind, receiver, propertyName,
-                interfaceTarget: member, resultType: readType)
-              ..fileOffset = fileOffset;
-          } else {
-            read = new InstanceGet(kind, receiver, propertyName,
-                interfaceTarget: member, resultType: readType)
-              ..fileOffset = fileOffset;
-          }
+
+        InstanceAccessKind kind;
+        switch (readTarget.kind) {
+          case ObjectAccessTargetKind.instanceMember:
+            kind = InstanceAccessKind.Instance;
+            break;
+          case ObjectAccessTargetKind.nullableInstanceMember:
+            kind = InstanceAccessKind.Nullable;
+            break;
+          case ObjectAccessTargetKind.objectMember:
+            kind = InstanceAccessKind.Object;
+            break;
+          default:
+            throw new UnsupportedError('Unexpected target kind $readTarget');
+        }
+        if (member is Procedure && member.kind == ProcedureKind.Method) {
+          read = new InstanceTearOff(kind, receiver, propertyName,
+              interfaceTarget: member, resultType: readType)
+            ..fileOffset = fileOffset;
         } else {
-          read = new PropertyGet(receiver, propertyName, readTarget.member)
+          read = new InstanceGet(kind, receiver, propertyName,
+              interfaceTarget: member, resultType: readType)
             ..fileOffset = fileOffset;
         }
         bool checkReturn = false;
@@ -5124,66 +4881,42 @@
         }
         break;
       case ObjectAccessTargetKind.invalid:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          write = new DynamicSet(
-              DynamicAccessKind.Invalid, receiver, propertyName, value)
-            ..fileOffset = fileOffset;
-        } else {
-          write =
-              new PropertySet(receiver, propertyName, value, writeTarget.member)
-                ..fileOffset = fileOffset;
-        }
+        write = new DynamicSet(
+            DynamicAccessKind.Invalid, receiver, propertyName, value)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.never:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          write = new DynamicSet(
-              DynamicAccessKind.Never, receiver, propertyName, value)
-            ..fileOffset = fileOffset;
-        } else {
-          write =
-              new PropertySet(receiver, propertyName, value, writeTarget.member)
-                ..fileOffset = fileOffset;
-        }
+        write = new DynamicSet(
+            DynamicAccessKind.Never, receiver, propertyName, value)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.callFunction:
       case ObjectAccessTargetKind.nullableCallFunction:
       case ObjectAccessTargetKind.dynamic:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          write = new DynamicSet(
-              DynamicAccessKind.Dynamic, receiver, propertyName, value)
-            ..fileOffset = fileOffset;
-        } else {
-          write =
-              new PropertySet(receiver, propertyName, value, writeTarget.member)
-                ..fileOffset = fileOffset;
-        }
+        write = new DynamicSet(
+            DynamicAccessKind.Dynamic, receiver, propertyName, value)
+          ..fileOffset = fileOffset;
         break;
       case ObjectAccessTargetKind.instanceMember:
       case ObjectAccessTargetKind.objectMember:
       case ObjectAccessTargetKind.nullableInstanceMember:
-        if (inferrer.useNewMethodInvocationEncoding) {
-          InstanceAccessKind kind;
-          switch (writeTarget.kind) {
-            case ObjectAccessTargetKind.instanceMember:
-              kind = InstanceAccessKind.Instance;
-              break;
-            case ObjectAccessTargetKind.nullableInstanceMember:
-              kind = InstanceAccessKind.Nullable;
-              break;
-            case ObjectAccessTargetKind.objectMember:
-              kind = InstanceAccessKind.Object;
-              break;
-            default:
-              throw new UnsupportedError('Unexpected target kind $writeTarget');
-          }
-          write = new InstanceSet(kind, receiver, propertyName, value,
-              interfaceTarget: writeTarget.member!)
-            ..fileOffset = fileOffset;
-        } else {
-          write =
-              new PropertySet(receiver, propertyName, value, writeTarget.member)
-                ..fileOffset = fileOffset;
+        InstanceAccessKind kind;
+        switch (writeTarget.kind) {
+          case ObjectAccessTargetKind.instanceMember:
+            kind = InstanceAccessKind.Instance;
+            break;
+          case ObjectAccessTargetKind.nullableInstanceMember:
+            kind = InstanceAccessKind.Nullable;
+            break;
+          case ObjectAccessTargetKind.objectMember:
+            kind = InstanceAccessKind.Object;
+            break;
+          default:
+            throw new UnsupportedError('Unexpected target kind $writeTarget');
         }
+        write = new InstanceSet(kind, receiver, propertyName, value,
+            interfaceTarget: writeTarget.member!)
+          ..fileOffset = fileOffset;
         break;
     }
     if (!inferrer.isTopLevel && writeTarget.isNullable) {
@@ -5875,51 +5608,11 @@
     return new ExpressionInferenceResult(inferredType, node);
   }
 
-  @override
-  ExpressionInferenceResult visitPropertySet(
-      covariant PropertySetImpl node, DartType typeContext) {
-    ExpressionInferenceResult receiverResult = inferrer
-        .inferNullAwareExpression(node.receiver, const UnknownType(), true,
-            isVoidAllowed: false);
-
-    Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
-    Expression receiver = receiverResult.nullAwareAction;
-    DartType receiverType = receiverResult.nullAwareActionType;
-
-    ObjectAccessTarget target = inferrer.findInterfaceMember(
-        receiverType, node.name, node.fileOffset,
-        setter: true, instrumented: true, includeExtensionMethods: true);
-    if (target.isInstanceMember || target.isObjectMember) {
-      if (inferrer.instrumentation != null &&
-          receiverType == const DynamicType()) {
-        inferrer.instrumentation!.record(
-            inferrer.uriForInstrumentation,
-            node.fileOffset,
-            'target',
-            new InstrumentationValueForMember(target.member!));
-      }
-      node.interfaceTarget = target.member;
-    }
-    DartType writeContext = inferrer.getSetterType(target, receiverType);
-    ExpressionInferenceResult rhsResult = inferrer
-        .inferExpression(node.value, writeContext, true, isVoidAllowed: true);
-    DartType rhsType = rhsResult.inferredType;
-    Expression rhs = inferrer.ensureAssignableResult(writeContext, rhsResult,
-        fileOffset: node.fileOffset, isVoidAllowed: writeContext is VoidType);
-
-    Expression replacement = _computePropertySet(
-        node.fileOffset, receiver, receiverType, node.name, target, rhs,
-        valueType: rhsType, forEffect: node.forEffect);
-
-    return inferrer.createNullAwareExpressionInferenceResult(
-        rhsType, replacement, nullAwareGuards);
-  }
-
   ExpressionInferenceResult visitInternalPropertySet(
       InternalPropertySet node, DartType typeContext) {
     ExpressionInferenceResult receiverResult = inferrer
         .inferNullAwareExpression(node.receiver, const UnknownType(), true,
-        isVoidAllowed: false);
+            isVoidAllowed: false);
 
     Link<NullAwareGuard> nullAwareGuards = receiverResult.nullAwareGuards;
     Expression receiver = receiverResult.nullAwareAction;
@@ -6057,32 +5750,6 @@
         inferredType, replacement, nullAwareGuards.prepend(nullAwareGuard));
   }
 
-  @override
-  ExpressionInferenceResult visitPropertyGet(
-      PropertyGet node, DartType typeContext) {
-    ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
-        node.receiver, const UnknownType(), true);
-
-    Link<NullAwareGuard> nullAwareGuards = result.nullAwareGuards;
-    Expression receiver = result.nullAwareAction;
-    DartType receiverType = result.nullAwareActionType;
-
-    node.receiver = receiver..parent = node;
-    PropertyGetInferenceResult propertyGetInferenceResult = _computePropertyGet(
-        node.fileOffset, receiver, receiverType, node.name, typeContext,
-        isThisReceiver: node.receiver is ThisExpression);
-    ExpressionInferenceResult readResult =
-        propertyGetInferenceResult.expressionInferenceResult;
-    inferrer.flowAnalysis.propertyGet(node, node.receiver, node.name.text,
-        propertyGetInferenceResult.member, readResult.inferredType);
-    ExpressionInferenceResult expressionInferenceResult =
-        inferrer.createNullAwareExpressionInferenceResult(
-            readResult.inferredType, readResult.expression, nullAwareGuards);
-    inferrer.flowAnalysis
-        .forwardExpression(expressionInferenceResult.nullAwareAction, node);
-    return expressionInferenceResult;
-  }
-
   ExpressionInferenceResult visitInternalPropertyGet(
       InternalPropertyGet node, DartType typeContext) {
     ExpressionInferenceResult result = inferrer.inferNullAwareExpression(
@@ -6284,11 +5951,8 @@
     }
 
     if (target is Procedure && target.kind == ProcedureKind.Method) {
-      Expression tearOff = node;
-      if (inferrer.useNewMethodInvocationEncoding) {
-        tearOff = new StaticTearOff(node.target as Procedure)
-          ..fileOffset = node.fileOffset;
-      }
+      Expression tearOff = new StaticTearOff(node.target as Procedure)
+        ..fileOffset = node.fileOffset;
       return inferrer.instantiateTearOff(type, typeContext, tearOff);
     } else {
       return new ExpressionInferenceResult(type, node);
@@ -6687,18 +6351,10 @@
     DartType resultType = rhsResult.inferredType;
     Expression resultExpression;
     if (variable.lateSetter != null) {
-      if (inferrer.useNewMethodInvocationEncoding) {
-        resultExpression = new LocalFunctionInvocation(variable.lateSetter!,
-            new Arguments(<Expression>[rhs])..fileOffset = node.fileOffset,
-            functionType: variable.lateSetter!.type as FunctionType)
-          ..fileOffset = node.fileOffset;
-      } else {
-        resultExpression = new MethodInvocation(
-            new VariableGet(variable.lateSetter!)..fileOffset = node.fileOffset,
-            callName,
-            new Arguments(<Expression>[rhs])..fileOffset = node.fileOffset)
-          ..fileOffset = node.fileOffset;
-      }
+      resultExpression = new LocalFunctionInvocation(variable.lateSetter!,
+          new Arguments(<Expression>[rhs])..fileOffset = node.fileOffset,
+          functionType: variable.lateSetter!.type as FunctionType)
+        ..fileOffset = node.fileOffset;
       // Future calls to flow analysis will be using `resultExpression` to refer
       // to the variable set, so instruct flow analysis to forward the
       // expression information.
@@ -6832,8 +6488,7 @@
         result.add(isSetVariable);
       }
 
-      Expression createVariableRead(bool useNewMethodInvocationEncoding,
-          {bool needsPromotion: false}) {
+      Expression createVariableRead({bool needsPromotion: false}) {
         if (needsPromotion) {
           return new VariableGet(node, node.type)..fileOffset = fileOffset;
         } else {
@@ -6857,11 +6512,7 @@
           new FunctionNode(
               node.initializer == null
                   ? late_lowering.createGetterBodyWithoutInitializer(
-                      inferrer.coreTypes,
-                      fileOffset,
-                      node.name!,
-                      node.type,
-                      inferrer.useNewMethodInvocationEncoding,
+                      inferrer.coreTypes, fileOffset, node.name!, node.type,
                       createVariableRead: createVariableRead,
                       createIsSetRead: createIsSetRead,
                       isSetEncoding: isSetEncoding,
@@ -6873,7 +6524,6 @@
                           node.name!,
                           node.type,
                           node.initializer!,
-                          inferrer.useNewMethodInvocationEncoding,
                           createVariableRead: createVariableRead,
                           createVariableWrite: createVariableWrite,
                           createIsSetRead: createIsSetRead,
@@ -6886,7 +6536,6 @@
                           node.name!,
                           node.type,
                           node.initializer!,
-                          inferrer.useNewMethodInvocationEncoding,
                           createVariableRead: createVariableRead,
                           createVariableWrite: createVariableWrite,
                           createIsSetRead: createIsSetRead,
@@ -6919,7 +6568,6 @@
                             node.name!,
                             setterParameter,
                             node.type,
-                            inferrer.useNewMethodInvocationEncoding,
                             shouldReturnValue: true,
                             createVariableRead: createVariableRead,
                             createVariableWrite: createVariableWrite,
@@ -6996,18 +6644,10 @@
     if (variable.isLocalFunction) {
       return inferrer.instantiateTearOff(resultType, typeContext, node);
     } else if (variable.lateGetter != null) {
-      if (inferrer.useNewMethodInvocationEncoding) {
-        resultExpression = new LocalFunctionInvocation(variable.lateGetter!,
-            new Arguments(<Expression>[])..fileOffset = node.fileOffset,
-            functionType: variable.lateGetter!.type as FunctionType)
-          ..fileOffset = node.fileOffset;
-      } else {
-        resultExpression = new MethodInvocation(
-            new VariableGet(variable.lateGetter!)..fileOffset = node.fileOffset,
-            callName,
-            new Arguments(<Expression>[])..fileOffset = node.fileOffset)
-          ..fileOffset = node.fileOffset;
-      }
+      resultExpression = new LocalFunctionInvocation(variable.lateGetter!,
+          new Arguments(<Expression>[])..fileOffset = node.fileOffset,
+          functionType: variable.lateGetter!.type as FunctionType)
+        ..fileOffset = node.fileOffset;
       // Future calls to flow analysis will be using `resultExpression` to refer
       // to the variable get, so instruct flow analysis to forward the
       // expression information.
@@ -7330,14 +6970,14 @@
   }
 }
 
-class PropertyForInVariable implements ForInVariable {
-  final PropertySet propertySet;
+class InternalPropertyForInVariable implements ForInVariable {
+  final InternalPropertySet propertySet;
 
   DartType? _writeType;
 
   Expression? _rhs;
 
-  PropertyForInVariable(this.propertySet);
+  InternalPropertyForInVariable(this.propertySet);
 
   @override
   DartType computeElementType(TypeInferrerImpl inferrer) {
@@ -7368,7 +7008,6 @@
               'target',
               new InstrumentationValueForMember(writeTarget.member!));
         }
-        propertySet.interfaceTarget = writeTarget.member;
       }
       _rhs = propertySet.value;
     }
@@ -7394,69 +7033,6 @@
   }
 }
 
-class InternalPropertyForInVariable implements ForInVariable {
-  final InternalPropertySet propertySet;
-
-  DartType? _writeType;
-
-  Expression? _rhs;
-
-  InternalPropertyForInVariable(this.propertySet);
-
-  @override
-  DartType computeElementType(TypeInferrerImpl inferrer) {
-    ExpressionInferenceResult receiverResult = inferrer.inferExpression(
-        propertySet.receiver, const UnknownType(), true);
-    propertySet.receiver = receiverResult.expression..parent = propertySet;
-    DartType receiverType = receiverResult.inferredType;
-    ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
-        receiverType, propertySet.name, propertySet.fileOffset,
-        setter: true, instrumented: true, includeExtensionMethods: true);
-    DartType elementType =
-    _writeType = inferrer.getSetterType(writeTarget, receiverType);
-    Expression? error = inferrer.reportMissingInterfaceMember(
-        writeTarget,
-        receiverType,
-        propertySet.name,
-        propertySet.fileOffset,
-        templateUndefinedSetter);
-    if (error != null) {
-      _rhs = error;
-    } else {
-      if (writeTarget.isInstanceMember || writeTarget.isObjectMember) {
-        if (inferrer.instrumentation != null &&
-            receiverType == const DynamicType()) {
-          inferrer.instrumentation!.record(
-              inferrer.uriForInstrumentation,
-              propertySet.fileOffset,
-              'target',
-              new InstrumentationValueForMember(writeTarget.member!));
-        }
-      }
-      _rhs = propertySet.value;
-    }
-    return elementType;
-  }
-
-  @override
-  Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
-    Expression rhs = inferrer.ensureAssignable(
-        inferrer.computeGreatestClosure(_writeType!), rhsType, _rhs!,
-        errorTemplate: templateForInLoopElementTypeNotAssignable,
-        nullabilityErrorTemplate:
-        templateForInLoopElementTypeNotAssignableNullability,
-        nullabilityPartErrorTemplate:
-        templateForInLoopElementTypeNotAssignablePartNullability,
-        isVoidAllowed: true);
-
-    propertySet.value = rhs..parent = propertySet;
-    ExpressionInferenceResult result = inferrer.inferExpression(
-        propertySet, const UnknownType(), !inferrer.isTopLevel,
-        isVoidAllowed: true);
-    return result.expression;
-  }
-}
-
 class SuperPropertyForInVariable implements ForInVariable {
   final SuperPropertySet superPropertySet;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
index 9389905..d207717 100644
--- a/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/internal_ast.dart
@@ -1254,7 +1254,7 @@
   @override
   void toTextInternal(AstPrinter printer) {
     Expression methodInvocation = invocation;
-    if (methodInvocation is MethodInvocation) {
+    if (methodInvocation is InstanceInvocation) {
       Expression receiver = methodInvocation.receiver;
       if (receiver is VariableGet && receiver.variable == variable) {
         // Special-case the usual use of this node.
@@ -1265,6 +1265,16 @@
         printer.writeArguments(methodInvocation.arguments);
         return;
       }
+    } else if (methodInvocation is DynamicInvocation) {
+      Expression receiver = methodInvocation.receiver;
+      if (receiver is VariableGet && receiver.variable == variable) {
+        // Special-case the usual use of this node.
+        printer.writeExpression(variable.initializer!);
+        printer.write('?.');
+        printer.writeName(methodInvocation.name);
+        printer.writeArguments(methodInvocation.arguments);
+        return;
+      }
     }
     printer.write('let ');
     printer.writeVariableDeclaration(variable);
@@ -1438,7 +1448,7 @@
   @override
   void toTextInternal(AstPrinter printer) {
     Expression propertySet = write;
-    if (propertySet is PropertySet) {
+    if (propertySet is InstanceSet) {
       Expression receiver = propertySet.receiver;
       if (receiver is VariableGet && receiver.variable == variable) {
         // Special-case the usual use of this node.
@@ -1450,6 +1460,17 @@
         printer.writeExpression(propertySet.value);
         return;
       }
+    } else if (propertySet is DynamicSet) {
+      Expression receiver = propertySet.receiver;
+      if (receiver is VariableGet && receiver.variable == variable) {
+        // Special-case the usual use of this node.
+        printer.writeExpression(variable.initializer!);
+        printer.write('?.');
+        printer.writeName(propertySet.name);
+        printer.write(' = ');
+        printer.writeExpression(propertySet.value);
+        return;
+      }
     }
     printer.write('let ');
     printer.writeVariableDeclaration(variable);
@@ -4101,29 +4122,6 @@
   }
 }
 
-/// Front end specific implementation of [PropertySet].
-class PropertySetImpl extends PropertySet {
-  /// If `true` the assignment is need for its effect and not for its value.
-  final bool forEffect;
-
-  /// If `true` the receiver can be cloned and doesn't need a temporary variable
-  /// for multiple reads.
-  final bool readOnlyReceiver;
-
-  PropertySetImpl(Expression receiver, Name name, Expression value,
-      {required this.forEffect, required this.readOnlyReceiver})
-      // ignore: unnecessary_null_comparison
-      : assert(forEffect != null),
-        // ignore: unnecessary_null_comparison
-        assert(readOnlyReceiver != null),
-        super(receiver, name, value);
-
-  @override
-  String toString() {
-    return "PropertySetImpl(${toStringInternal()})";
-  }
-}
-
 /// Internal representation of a read of an extension instance member.
 ///
 /// A read of an extension instance member `o.foo` is encoded as the
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index 775003f..7c62ddb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -48,7 +48,6 @@
         MapLiteralEntry,
         MapLiteral,
         Member,
-        MethodInvocation,
         Name,
         NamedExpression,
         NamedType,
@@ -56,8 +55,6 @@
         NullLiteral,
         Procedure,
         ProcedureKind,
-        PropertyGet,
-        PropertySet,
         Rethrow,
         ReturnStatement,
         Statement,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index fb00d81..633f674 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1253,9 +1253,7 @@
     if (loader.target.context.options
         .isExperimentEnabledGlobally(ExperimentalFlag.valueClass)) {
       valueClass.transformComponent(
-          component!, loader.coreTypes, loader.hierarchy, environment,
-          useNewMethodInvocationEncoding:
-              backendTarget.supportsNewMethodInvocationEncoding);
+          component!, loader.coreTypes, loader.hierarchy, environment);
       ticker.logMs("Lowered value classes");
     }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index 8a9c80c..4f1045c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -7,7 +7,6 @@
 
 import '../../base/nnbd_mode.dart';
 import '../source/source_library_builder.dart';
-import '../names.dart';
 
 const String lateFieldPrefix = '_#';
 const String lateIsSetSuffix = '#isSet';
@@ -20,15 +19,9 @@
 ///
 /// Late final fields and locals need to detect writes during initialization and
 /// therefore uses [createGetterWithInitializerWithRecheck] instead.
-Statement createGetterWithInitializer(
-    CoreTypes coreTypes,
-    int fileOffset,
-    String name,
-    DartType type,
-    Expression initializer,
-    bool useNewMethodInvocationEncoding,
-    {required Expression createVariableRead(bool useNewMethodInvocationEncoding,
-        {bool needsPromotion}),
+Statement createGetterWithInitializer(CoreTypes coreTypes, int fileOffset,
+    String name, DartType type, Expression initializer,
+    {required Expression createVariableRead({bool needsPromotion}),
     required Expression createVariableWrite(Expression value),
     required Expression createIsSetRead(),
     required Expression createIsSetWrite(Expression value),
@@ -64,8 +57,7 @@
             // If [type] is a type variable with undetermined nullability we
             // need to create a read of the field that is promoted to the type
             // variable type.
-            createVariableRead(useNewMethodInvocationEncoding,
-                needsPromotion: type.isPotentiallyNonNullable))
+            createVariableRead(needsPromotion: type.isPotentiallyNonNullable))
           ..fileOffset = fileOffset
       ])
         ..fileOffset = fileOffset;
@@ -74,9 +66,7 @@
       //
       //    return let # = _#field in isSentinel(#) ? _#field = <init> : #;
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          createVariableRead(useNewMethodInvocationEncoding,
-              needsPromotion: false)
-            ..fileOffset = fileOffset,
+          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
           type: type.withDeclaredNullability(Nullability.nullable))
         ..fileOffset = fileOffset;
       return new ReturnStatement(
@@ -101,46 +91,30 @@
       //
       //    return let # = _#field in # == null ? _#field = <init> : #;
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          createVariableRead(useNewMethodInvocationEncoding,
-              needsPromotion: false)
-            ..fileOffset = fileOffset,
+          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
           type: type.withDeclaredNullability(Nullability.nullable))
         ..fileOffset = fileOffset;
-      return new ReturnStatement(new Let(
-          variable,
-          new ConditionalExpression(
-              useNewMethodInvocationEncoding
-                  ? (new EqualsNull(
+      return new ReturnStatement(
+          new Let(
+              variable,
+              new ConditionalExpression(
+                  new EqualsNull(
                       new VariableGet(variable)..fileOffset = fileOffset)
-                    ..fileOffset = fileOffset)
-                  : new MethodInvocation(
-                      new VariableGet(variable)..fileOffset = fileOffset,
-                      equalsName,
-                      new Arguments(<Expression>[
-                        new NullLiteral()..fileOffset = fileOffset
-                      ])
-                        ..fileOffset = fileOffset)
-                ..fileOffset = fileOffset,
-              createVariableWrite(initializer)..fileOffset = fileOffset,
-              new VariableGet(variable, type)..fileOffset = fileOffset,
-              type)
+                    ..fileOffset = fileOffset,
+                  createVariableWrite(initializer)..fileOffset = fileOffset,
+                  new VariableGet(variable, type)..fileOffset = fileOffset,
+                  type)
+                ..fileOffset = fileOffset)
             ..fileOffset = fileOffset)
-        ..fileOffset = fileOffset)
         ..fileOffset = fileOffset;
   }
 }
 
 /// Creates the body for the synthesized getter used to encode the lowering
 /// of a late final field or local with an initializer.
-Statement createGetterWithInitializerWithRecheck(
-    CoreTypes coreTypes,
-    int fileOffset,
-    String name,
-    DartType type,
-    Expression initializer,
-    bool useNewMethodInvocationEncoding,
-    {required Expression createVariableRead(bool useNewMethodInvocationEncoding,
-        {bool needsPromotion}),
+Statement createGetterWithInitializerWithRecheck(CoreTypes coreTypes,
+    int fileOffset, String name, DartType type, Expression initializer,
+    {required Expression createVariableRead({bool needsPromotion}),
     required Expression createVariableWrite(Expression value),
     required Expression createIsSetRead(),
     required Expression createIsSetWrite(Expression value),
@@ -202,8 +176,7 @@
             // If [type] is a type variable with undetermined nullability we
             // need to create a read of the field that is promoted to the type
             // variable type.
-            createVariableRead(useNewMethodInvocationEncoding,
-                needsPromotion: type.isPotentiallyNonNullable))
+            createVariableRead(needsPromotion: type.isPotentiallyNonNullable))
           ..fileOffset = fileOffset
       ])
         ..fileOffset = fileOffset;
@@ -215,43 +188,41 @@
       //            ? _#field = #2 : throw '...'
       //        : #1;
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          createVariableRead(useNewMethodInvocationEncoding,
-              needsPromotion: false)
-            ..fileOffset = fileOffset,
+          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
           type: type)
         ..fileOffset = fileOffset;
-      return new ReturnStatement(new Let(
-          variable,
-          new ConditionalExpression(
-              new StaticInvocation(
-                  coreTypes.isSentinelMethod,
-                  new Arguments(<Expression>[
-                    new VariableGet(variable)..fileOffset = fileOffset
-                  ])
-                    ..fileOffset = fileOffset)
-                ..fileOffset = fileOffset,
-              new Let(
-                  temp,
-                  new ConditionalExpression(
-                      new StaticInvocation(
-                          coreTypes.isSentinelMethod,
-                          new Arguments(<Expression>[
-                            createVariableRead(useNewMethodInvocationEncoding,
-                                needsPromotion: false)
-                              ..fileOffset = fileOffset
-                          ])
-                            ..fileOffset = fileOffset)
-                        ..fileOffset = fileOffset,
-                      createVariableWrite(
-                          new VariableGet(temp)..fileOffset = fileOffset)
-                        ..fileOffset = fileOffset,
-                      exception,
-                      type)
-                    ..fileOffset = fileOffset),
-              new VariableGet(variable)..fileOffset = fileOffset,
-              type)
+      return new ReturnStatement(
+          new Let(
+              variable,
+              new ConditionalExpression(
+                  new StaticInvocation(
+                      coreTypes.isSentinelMethod,
+                      new Arguments(<Expression>[
+                        new VariableGet(variable)..fileOffset = fileOffset
+                      ])
+                        ..fileOffset = fileOffset)
+                    ..fileOffset = fileOffset,
+                  new Let(
+                      temp,
+                      new ConditionalExpression(
+                          new StaticInvocation(
+                              coreTypes.isSentinelMethod,
+                              new Arguments(<Expression>[
+                                createVariableRead(needsPromotion: false)
+                                  ..fileOffset = fileOffset
+                              ])
+                                ..fileOffset = fileOffset)
+                            ..fileOffset = fileOffset,
+                          createVariableWrite(
+                              new VariableGet(temp)..fileOffset = fileOffset)
+                            ..fileOffset = fileOffset,
+                          exception,
+                          type)
+                        ..fileOffset = fileOffset),
+                  new VariableGet(variable)..fileOffset = fileOffset,
+                  type)
+                ..fileOffset = fileOffset)
             ..fileOffset = fileOffset)
-        ..fileOffset = fileOffset)
         ..fileOffset = fileOffset;
     case IsSetEncoding.useNull:
       // Generate:
@@ -261,55 +232,33 @@
       //            ? _#field = #2 : throw '...'
       //        : #1;
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          createVariableRead(useNewMethodInvocationEncoding,
-              needsPromotion: false)
-            ..fileOffset = fileOffset,
+          createVariableRead(needsPromotion: false)..fileOffset = fileOffset,
           type: type.withDeclaredNullability(Nullability.nullable))
         ..fileOffset = fileOffset;
-      return new ReturnStatement(new Let(
-          variable,
-          new ConditionalExpression(
-              useNewMethodInvocationEncoding
-                  ? (new EqualsNull(
+      return new ReturnStatement(
+          new Let(
+              variable,
+              new ConditionalExpression(
+                  new EqualsNull(
                       new VariableGet(variable)..fileOffset = fileOffset)
-                    ..fileOffset = fileOffset)
-                  : new MethodInvocation(
-                      new VariableGet(variable)..fileOffset = fileOffset,
-                      equalsName,
-                      new Arguments(<Expression>[
-                        new NullLiteral()..fileOffset = fileOffset
-                      ])
-                        ..fileOffset = fileOffset)
-                ..fileOffset = fileOffset,
-              new Let(
-                  temp,
-                  new ConditionalExpression(
-                      useNewMethodInvocationEncoding
-                          ? (new EqualsNull(
-                              createVariableRead(useNewMethodInvocationEncoding,
-                                  needsPromotion: false)
+                    ..fileOffset = fileOffset,
+                  new Let(
+                      temp,
+                      new ConditionalExpression(
+                          new EqualsNull(
+                              createVariableRead(needsPromotion: false)
                                 ..fileOffset = fileOffset)
-                            ..fileOffset = fileOffset)
-                          : new MethodInvocation(
-                              createVariableRead(useNewMethodInvocationEncoding,
-                                  needsPromotion: false)
-                                ..fileOffset = fileOffset,
-                              equalsName,
-                              new Arguments(<Expression>[
-                                new NullLiteral()..fileOffset = fileOffset
-                              ])
-                                ..fileOffset = fileOffset)
-                        ..fileOffset = fileOffset,
-                      createVariableWrite(
-                          new VariableGet(temp)..fileOffset = fileOffset)
-                        ..fileOffset = fileOffset,
-                      exception,
-                      type)
-                    ..fileOffset = fileOffset),
-              new VariableGet(variable, type)..fileOffset = fileOffset,
-              type)
+                            ..fileOffset = fileOffset,
+                          createVariableWrite(
+                              new VariableGet(temp)..fileOffset = fileOffset)
+                            ..fileOffset = fileOffset,
+                          exception,
+                          type)
+                        ..fileOffset = fileOffset),
+                  new VariableGet(variable, type)..fileOffset = fileOffset,
+                  type)
+                ..fileOffset = fileOffset)
             ..fileOffset = fileOffset)
-        ..fileOffset = fileOffset)
         ..fileOffset = fileOffset;
   }
 }
@@ -317,13 +266,8 @@
 /// Creates the body for the synthesized getter used to encode the lowering
 /// of a late field or local without an initializer.
 Statement createGetterBodyWithoutInitializer(
-    CoreTypes coreTypes,
-    int fileOffset,
-    String name,
-    DartType type,
-    bool useNewMethodInvocationEncoding,
-    {required Expression createVariableRead(bool useNewMethodInvocationEncoding,
-        {bool needsPromotion}),
+    CoreTypes coreTypes, int fileOffset, String name, DartType type,
+    {required Expression createVariableRead({bool needsPromotion}),
     required Expression createIsSetRead(),
     required IsSetEncoding isSetEncoding,
     required bool forField}) {
@@ -349,8 +293,7 @@
       return new ReturnStatement(
           new ConditionalExpression(
               createIsSetRead()..fileOffset = fileOffset,
-              createVariableRead(useNewMethodInvocationEncoding,
-                  needsPromotion: type.isPotentiallyNonNullable)
+              createVariableRead(needsPromotion: type.isPotentiallyNonNullable)
                 ..fileOffset = fileOffset,
               exception,
               type)
@@ -361,8 +304,7 @@
       //
       //    return let # = _#field in isSentinel(#) ? throw '...' : #;
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          createVariableRead(useNewMethodInvocationEncoding)
-            ..fileOffset = fileOffset,
+          createVariableRead()..fileOffset = fileOffset,
           type: type.withDeclaredNullability(Nullability.nullable))
         ..fileOffset = fileOffset;
       return new ReturnStatement(
@@ -387,30 +329,21 @@
       //
       //    return let # = _#field in # == null ? throw '...' : #;
       VariableDeclaration variable = new VariableDeclaration.forValue(
-          createVariableRead(useNewMethodInvocationEncoding)
-            ..fileOffset = fileOffset,
+          createVariableRead()..fileOffset = fileOffset,
           type: type.withDeclaredNullability(Nullability.nullable))
         ..fileOffset = fileOffset;
-      return new ReturnStatement(new Let(
-          variable,
-          new ConditionalExpression(
-              useNewMethodInvocationEncoding
-                  ? (new EqualsNull(
+      return new ReturnStatement(
+          new Let(
+              variable,
+              new ConditionalExpression(
+                  new EqualsNull(
                       new VariableGet(variable)..fileOffset = fileOffset)
-                    ..fileOffset = fileOffset)
-                  : new MethodInvocation(
-                      new VariableGet(variable)..fileOffset = fileOffset,
-                      equalsName,
-                      new Arguments(<Expression>[
-                        new NullLiteral()..fileOffset = fileOffset
-                      ])
-                        ..fileOffset = fileOffset)
-                ..fileOffset = fileOffset,
-              exception,
-              new VariableGet(variable, type)..fileOffset = fileOffset,
-              type)
+                    ..fileOffset = fileOffset,
+                  exception,
+                  new VariableGet(variable, type)..fileOffset = fileOffset,
+                  type)
+                ..fileOffset = fileOffset)
             ..fileOffset = fileOffset)
-        ..fileOffset = fileOffset)
         ..fileOffset = fileOffset;
   }
 }
@@ -464,15 +397,10 @@
 
 /// Creates the body for the synthesized setter used to encode the lowering
 /// of a final late field or local.
-Statement createSetterBodyFinal(
-    CoreTypes coreTypes,
-    int fileOffset,
-    String name,
-    VariableDeclaration parameter,
-    DartType type,
-    bool useNewMethodInvocationEncoding,
+Statement createSetterBodyFinal(CoreTypes coreTypes, int fileOffset,
+    String name, VariableDeclaration parameter, DartType type,
     {required bool shouldReturnValue,
-    required Expression createVariableRead(bool useNewMethodInvocationEncoding),
+    required Expression createVariableRead(),
     required Expression createVariableWrite(Expression value),
     required Expression createIsSetRead(),
     required Expression createIsSetWrite(Expression value),
@@ -536,10 +464,8 @@
       return new IfStatement(
         new StaticInvocation(
             coreTypes.isSentinelMethod,
-            new Arguments(<Expression>[
-              createVariableRead(useNewMethodInvocationEncoding)
-                ..fileOffset = fileOffset
-            ])
+            new Arguments(
+                <Expression>[createVariableRead()..fileOffset = fileOffset])
               ..fileOffset = fileOffset)
           ..fileOffset = fileOffset,
         createReturn(createVariableWrite(
@@ -556,18 +482,7 @@
       //      throw '...';
       //    }
       return new IfStatement(
-        useNewMethodInvocationEncoding
-            ? (new EqualsNull(
-                createVariableRead(useNewMethodInvocationEncoding)
-                  ..fileOffset = fileOffset)
-              ..fileOffset = fileOffset)
-            : new MethodInvocation(
-                createVariableRead(useNewMethodInvocationEncoding)
-                  ..fileOffset = fileOffset,
-                equalsName,
-                new Arguments(
-                    <Expression>[new NullLiteral()..fileOffset = fileOffset])
-                  ..fileOffset = fileOffset)
+        new EqualsNull(createVariableRead()..fileOffset = fileOffset)
           ..fileOffset = fileOffset,
         createReturn(createVariableWrite(
             new VariableGet(parameter)..fileOffset = fileOffset)
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index af26d1b..ed6516b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -46,7 +46,6 @@
   final Procedure _setAddAll;
   late final FunctionType _setAddAllFunctionType;
   final Procedure _setOf;
-  final Procedure _objectEquals;
   final Procedure _mapEntries;
   final Procedure _mapPut;
   late final FunctionType _mapPutFunctionType;
@@ -54,7 +53,6 @@
   final Field _mapEntryKey;
   final Field _mapEntryValue;
   final SourceLoaderDataForTesting? _dataForTesting;
-  final bool useNewMethodInvocationEncoding;
 
   /// Library that contains the transformed nodes.
   ///
@@ -83,8 +81,6 @@
         _setAddAll =
             _loader.coreTypes.index.getProcedure('dart:core', 'Set', 'addAll'),
         _setOf = _findSetFactory(_loader.coreTypes, 'of'),
-        _objectEquals =
-            _loader.coreTypes.index.getProcedure('dart:core', 'Object', '=='),
         _mapEntries = _loader.coreTypes.index
             .getProcedure('dart:core', 'Map', 'get:entries'),
         _mapPut =
@@ -95,9 +91,7 @@
             _loader.coreTypes.index.getField('dart:core', 'MapEntry', 'key'),
         _mapEntryValue =
             _loader.coreTypes.index.getField('dart:core', 'MapEntry', 'value'),
-        _dataForTesting = _loader.dataForTesting,
-        useNewMethodInvocationEncoding =
-            _loader.target.backendTarget.supportsNewMethodInvocationEncoding {
+        _dataForTesting = _loader.dataForTesting {
     _listAddFunctionType = _listAdd.getterType as FunctionType;
     _listAddAllFunctionType = _listAddAll.getterType as FunctionType;
     _setAddFunctionType = _setAdd.getterType as FunctionType;
@@ -908,24 +902,17 @@
     assert(argument != null);
     assert(argument.fileOffset != TreeNode.noOffset,
         "No fileOffset on ${argument}.");
-    if (useNewMethodInvocationEncoding) {
-      DartType functionType = Substitution.fromInterfaceType(receiverType)
-          .substituteType(isSet ? _setAddFunctionType : _listAddFunctionType);
-      if (!_currentLibrary!.isNonNullableByDefault) {
-        functionType = legacyErasure(functionType);
-      }
-      return new InstanceInvocation(InstanceAccessKind.Instance, receiver,
-          new Name('add'), new Arguments([argument]),
-          functionType: functionType as FunctionType,
-          interfaceTarget: isSet ? _setAdd : _listAdd)
-        ..fileOffset = argument.fileOffset
-        ..isInvariant = true;
-    } else {
-      return new MethodInvocation(receiver, new Name('add'),
-          new Arguments([argument]), isSet ? _setAdd : _listAdd)
-        ..fileOffset = argument.fileOffset
-        ..isInvariant = true;
+    DartType functionType = Substitution.fromInterfaceType(receiverType)
+        .substituteType(isSet ? _setAddFunctionType : _listAddFunctionType);
+    if (!_currentLibrary!.isNonNullableByDefault) {
+      functionType = legacyErasure(functionType);
     }
+    return new InstanceInvocation(InstanceAccessKind.Instance, receiver,
+        new Name('add'), new Arguments([argument]),
+        functionType: functionType as FunctionType,
+        interfaceTarget: isSet ? _setAdd : _listAdd)
+      ..fileOffset = argument.fileOffset
+      ..isInvariant = true;
   }
 
   Expression _createAddAll(Expression receiver, InterfaceType receiverType,
@@ -936,43 +923,26 @@
     assert(argument != null);
     assert(argument.fileOffset != TreeNode.noOffset,
         "No fileOffset on ${argument}.");
-    if (useNewMethodInvocationEncoding) {
-      DartType functionType = Substitution.fromInterfaceType(receiverType)
-          .substituteType(
-              isSet ? _setAddAllFunctionType : _listAddAllFunctionType);
-      if (!_currentLibrary!.isNonNullableByDefault) {
-        functionType = legacyErasure(functionType);
-      }
-      return new InstanceInvocation(InstanceAccessKind.Instance, receiver,
-          new Name('addAll'), new Arguments([argument]),
-          functionType: functionType as FunctionType,
-          interfaceTarget: isSet ? _setAddAll : _listAddAll)
-        ..fileOffset = argument.fileOffset
-        ..isInvariant = true;
-    } else {
-      return new MethodInvocation(receiver, new Name('addAll'),
-          new Arguments([argument]), isSet ? _setAddAll : _listAddAll)
-        ..fileOffset = argument.fileOffset
-        ..isInvariant = true;
+    DartType functionType = Substitution.fromInterfaceType(receiverType)
+        .substituteType(
+            isSet ? _setAddAllFunctionType : _listAddAllFunctionType);
+    if (!_currentLibrary!.isNonNullableByDefault) {
+      functionType = legacyErasure(functionType);
     }
+    return new InstanceInvocation(InstanceAccessKind.Instance, receiver,
+        new Name('addAll'), new Arguments([argument]),
+        functionType: functionType as FunctionType,
+        interfaceTarget: isSet ? _setAddAll : _listAddAll)
+      ..fileOffset = argument.fileOffset
+      ..isInvariant = true;
   }
 
   Expression _createEqualsNull(Expression expression, {bool notEquals: false}) {
     // ignore: unnecessary_null_comparison
     assert(expression != null);
     assert(expression.fileOffset != TreeNode.noOffset);
-    Expression check;
-    if (useNewMethodInvocationEncoding) {
-      check = new EqualsNull(expression)..fileOffset = expression.fileOffset;
-    } else {
-      check = new MethodInvocation(
-          expression,
-          new Name('=='),
-          new Arguments(
-              [new NullLiteral()..fileOffset = expression.fileOffset]),
-          _objectEquals)
-        ..fileOffset = expression.fileOffset;
-    }
+    Expression check = new EqualsNull(expression)
+      ..fileOffset = expression.fileOffset;
     if (notEquals) {
       check = new Not(check)..fileOffset = expression.fileOffset;
     }
@@ -984,23 +954,16 @@
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    if (useNewMethodInvocationEncoding) {
-      DartType functionType = Substitution.fromInterfaceType(receiverType)
-          .substituteType(_mapPutFunctionType);
-      if (!_currentLibrary!.isNonNullableByDefault) {
-        functionType = legacyErasure(functionType);
-      }
-      return new InstanceInvocation(InstanceAccessKind.Instance, receiver,
-          new Name('[]='), new Arguments([key, value]),
-          functionType: functionType as FunctionType, interfaceTarget: _mapPut)
-        ..fileOffset = fileOffset
-        ..isInvariant = true;
-    } else {
-      return new MethodInvocation(
-          receiver, new Name('[]='), new Arguments([key, value]), _mapPut)
-        ..fileOffset = fileOffset
-        ..isInvariant = true;
+    DartType functionType = Substitution.fromInterfaceType(receiverType)
+        .substituteType(_mapPutFunctionType);
+    if (!_currentLibrary!.isNonNullableByDefault) {
+      functionType = legacyErasure(functionType);
     }
+    return new InstanceInvocation(InstanceAccessKind.Instance, receiver,
+        new Name('[]='), new Arguments([key, value]),
+        functionType: functionType as FunctionType, interfaceTarget: _mapPut)
+      ..fileOffset = fileOffset
+      ..isInvariant = true;
   }
 
   AsExpression _createImplicitAs(
@@ -1027,17 +990,12 @@
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    if (useNewMethodInvocationEncoding) {
-      DartType resultType = Substitution.fromInterfaceType(entryType)
-          .substituteType(_mapEntryKey.type);
-      return new InstanceGet(
-          InstanceAccessKind.Instance, receiver, new Name('key'),
-          interfaceTarget: _mapEntryKey, resultType: resultType)
-        ..fileOffset = fileOffset;
-    } else {
-      return new PropertyGet(receiver, new Name('key'), _mapEntryKey)
-        ..fileOffset = fileOffset;
-    }
+    DartType resultType = Substitution.fromInterfaceType(entryType)
+        .substituteType(_mapEntryKey.type);
+    return new InstanceGet(
+        InstanceAccessKind.Instance, receiver, new Name('key'),
+        interfaceTarget: _mapEntryKey, resultType: resultType)
+      ..fileOffset = fileOffset;
   }
 
   Expression _createGetValue(
@@ -1045,17 +1003,12 @@
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    if (useNewMethodInvocationEncoding) {
-      DartType resultType = Substitution.fromInterfaceType(entryType)
-          .substituteType(_mapEntryValue.type);
-      return new InstanceGet(
-          InstanceAccessKind.Instance, receiver, new Name('value'),
-          interfaceTarget: _mapEntryValue, resultType: resultType)
-        ..fileOffset = fileOffset;
-    } else {
-      return new PropertyGet(receiver, new Name('value'), _mapEntryValue)
-        ..fileOffset = fileOffset;
-    }
+    DartType resultType = Substitution.fromInterfaceType(entryType)
+        .substituteType(_mapEntryValue.type);
+    return new InstanceGet(
+        InstanceAccessKind.Instance, receiver, new Name('value'),
+        interfaceTarget: _mapEntryValue, resultType: resultType)
+      ..fileOffset = fileOffset;
   }
 
   Expression _createGetEntries(
@@ -1063,17 +1016,12 @@
     // ignore: unnecessary_null_comparison
     assert(fileOffset != null);
     assert(fileOffset != TreeNode.noOffset);
-    if (useNewMethodInvocationEncoding) {
-      DartType resultType = Substitution.fromInterfaceType(mapType)
-          .substituteType(_mapEntries.getterType);
-      return new InstanceGet(
-          InstanceAccessKind.Instance, receiver, new Name('entries'),
-          interfaceTarget: _mapEntries, resultType: resultType)
-        ..fileOffset = fileOffset;
-    } else {
-      return new PropertyGet(receiver, new Name('entries'), _mapEntries)
-        ..fileOffset = fileOffset;
-    }
+    DartType resultType = Substitution.fromInterfaceType(mapType)
+        .substituteType(_mapEntries.getterType);
+    return new InstanceGet(
+        InstanceAccessKind.Instance, receiver, new Name('entries'),
+        interfaceTarget: _mapEntries, resultType: resultType)
+      ..fileOffset = fileOffset;
   }
 
   ForStatement _createForStatement(
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart b/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
index 74246b0..4cab9fe 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
@@ -22,7 +22,6 @@
   final Procedure setFactory;
   final Procedure addMethod;
   late final FunctionType _addMethodFunctionType;
-  final bool useNewMethodInvocationEncoding;
 
   /// Library that contains the transformed nodes.
   ///
@@ -44,9 +43,7 @@
   SetLiteralTransformer(SourceLoader loader)
       : coreTypes = loader.coreTypes,
         setFactory = _findSetFactory(loader.coreTypes),
-        addMethod = _findAddMethod(loader.coreTypes),
-        useNewMethodInvocationEncoding =
-            loader.target.backendTarget.supportsNewMethodInvocationEncoding {
+        addMethod = _findAddMethod(loader.coreTypes) {
     _addMethodFunctionType = addMethod.getterType as FunctionType;
   }
 
@@ -65,25 +62,20 @@
     List<Statement> statements = [setVar];
     for (int i = 0; i < node.expressions.length; i++) {
       Expression entry = transform(node.expressions[i]);
-      Expression methodInvocation;
-      if (useNewMethodInvocationEncoding) {
-        DartType functionType = Substitution.fromInterfaceType(receiverType)
-            .substituteType(_addMethodFunctionType);
-        if (!_currentLibrary!.isNonNullableByDefault) {
-          functionType = legacyErasure(functionType);
-        }
-        methodInvocation = new InstanceInvocation(InstanceAccessKind.Instance,
-            new VariableGet(setVar), new Name("add"), new Arguments([entry]),
-            functionType: functionType as FunctionType,
-            interfaceTarget: addMethod)
-          ..fileOffset = entry.fileOffset
-          ..isInvariant = true;
-      } else {
-        methodInvocation = new MethodInvocation(new VariableGet(setVar),
-            new Name("add"), new Arguments([entry]), addMethod)
-          ..fileOffset = entry.fileOffset
-          ..isInvariant = true;
+      DartType functionType = Substitution.fromInterfaceType(receiverType)
+          .substituteType(_addMethodFunctionType);
+      if (!_currentLibrary!.isNonNullableByDefault) {
+        functionType = legacyErasure(functionType);
       }
+      Expression methodInvocation = new InstanceInvocation(
+          InstanceAccessKind.Instance,
+          new VariableGet(setVar),
+          new Name("add"),
+          new Arguments([entry]),
+          functionType: functionType as FunctionType,
+          interfaceTarget: addMethod)
+        ..fileOffset = entry.fileOffset
+        ..isInvariant = true;
       statements.add(new ExpressionStatement(methodInvocation)
         ..fileOffset = methodInvocation.fileOffset);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 4ac0b50..7c313ec 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -437,39 +437,6 @@
   }
 
   @override
-  void visitMethodInvocation(MethodInvocation node) {
-    if (target.supportsNewMethodInvocationEncoding) {
-      problem(
-          node,
-          "New method invocation encoding is supported, "
-          "but found a MethodInvocation.");
-    }
-    super.visitMethodInvocation(node);
-  }
-
-  @override
-  void visitPropertyGet(PropertyGet node) {
-    if (target.supportsNewMethodInvocationEncoding) {
-      problem(
-          node,
-          "New method invocation encoding is supported, "
-          "but found a PropertyGet.");
-    }
-    super.visitPropertyGet(node);
-  }
-
-  @override
-  void visitPropertySet(PropertySet node) {
-    if (target.supportsNewMethodInvocationEncoding) {
-      problem(
-          node,
-          "New method invocation encoding is supported, "
-          "but found a PropertySet.");
-    }
-    super.visitPropertySet(node);
-  }
-
-  @override
   void defaultTreeNode(TreeNode node) {
     enterTreeNode(node);
     super.defaultTreeNode(node);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index d81529e..395a4d2 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -829,19 +829,11 @@
         new Arguments.forwarded(procedure.function, library.library),
         procedure.fileOffset,
         /*isSuper=*/ false);
-    Expression result;
-    if (library
-        .loader.target.backendTarget.supportsNewMethodInvocationEncoding) {
-      result = new InstanceInvocation(InstanceAccessKind.Instance,
-          new ThisExpression(), noSuchMethodName, new Arguments([invocation]),
-          functionType: noSuchMethodInterface.getterType as FunctionType,
-          interfaceTarget: noSuchMethodInterface)
-        ..fileOffset = procedure.fileOffset;
-    } else {
-      result = new MethodInvocation(new ThisExpression(), noSuchMethodName,
-          new Arguments([invocation]), noSuchMethodInterface)
-        ..fileOffset = procedure.fileOffset;
-    }
+    Expression result = new InstanceInvocation(InstanceAccessKind.Instance,
+        new ThisExpression(), noSuchMethodName, new Arguments([invocation]),
+        functionType: noSuchMethodInterface.getterType as FunctionType,
+        interfaceTarget: noSuchMethodInterface)
+      ..fileOffset = procedure.fileOffset;
     if (procedure.function.returnType is! VoidType) {
       result = new AsExpression(result, procedure.function.returnType)
         ..isTypeError = true
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index db042b3..2bf3ff0 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -235,9 +235,6 @@
 
   NnbdMode get nnbdMode => library.loader.nnbdMode;
 
-  bool get useNewMethodInvocationEncoding =>
-      library.loader.target.backendTarget.supportsNewMethodInvocationEncoding;
-
   DartType get bottomType =>
       isNonNullableByDefault ? const NeverType.nonNullable() : const NullType();
 
@@ -760,32 +757,19 @@
     VariableDeclaration t =
         new VariableDeclaration.forValue(expression, type: expressionType)
           ..fileOffset = fileOffset;
-    Expression nullCheck;
+
     // TODO(johnniwinther): Avoid null-check for non-nullable expressions.
-    if (useNewMethodInvocationEncoding) {
-      nullCheck = new EqualsNull(new VariableGet(t)..fileOffset = fileOffset)
-        ..fileOffset = fileOffset;
-    } else {
-      nullCheck = new MethodInvocation(
-          new VariableGet(t)..fileOffset = fileOffset,
-          equalsName,
-          new Arguments(
-              <Expression>[new NullLiteral()..fileOffset = fileOffset]))
-        ..fileOffset = fileOffset;
-    }
-    Expression tearOff;
+    Expression nullCheck =
+        new EqualsNull(new VariableGet(t)..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
+
     DartType tearoffType =
         getGetterTypeForMemberTarget(callMember, expressionType)
             .withDeclaredNullability(expressionType.nullability);
-    if (useNewMethodInvocationEncoding) {
-      tearOff = new InstanceTearOff(
-          InstanceAccessKind.Instance, new VariableGet(t), callName,
-          interfaceTarget: callMember as Procedure, resultType: tearoffType)
-        ..fileOffset = fileOffset;
-    } else {
-      tearOff = new PropertyGet(new VariableGet(t), callName, callMember)
-        ..fileOffset = fileOffset;
-    }
+    Expression tearOff = new InstanceTearOff(
+        InstanceAccessKind.Instance, new VariableGet(t), callName,
+        interfaceTarget: callMember as Procedure, resultType: tearoffType)
+      ..fileOffset = fileOffset;
     ConditionalExpression conditional = new ConditionalExpression(nullCheck,
         new NullLiteral()..fileOffset = fileOffset, tearOff, tearoffType);
     return new TypedTearoff(
@@ -2768,15 +2752,9 @@
         receiverType: const DynamicType(),
         isImplicitCall: isImplicitCall);
     assert(name != equalsName);
-    Expression expression;
-    if (useNewMethodInvocationEncoding) {
-      expression = new DynamicInvocation(
-          DynamicAccessKind.Dynamic, receiver, name, arguments)
-        ..fileOffset = fileOffset;
-    } else {
-      expression = new MethodInvocation(receiver, name, arguments)
-        ..fileOffset = fileOffset;
-    }
+    Expression expression = new DynamicInvocation(
+        DynamicAccessKind.Dynamic, receiver, name, arguments)
+      ..fileOffset = fileOffset;
     return createNullAwareExpressionInferenceResult(
         result.inferredType, result.applyResult(expression), nullAwareGuards);
   }
@@ -2799,15 +2777,9 @@
         receiverType: receiverType,
         isImplicitCall: isImplicitCall);
     assert(name != equalsName);
-    Expression expression;
-    if (useNewMethodInvocationEncoding) {
-      expression = new DynamicInvocation(
-          DynamicAccessKind.Never, receiver, name, arguments)
-        ..fileOffset = fileOffset;
-    } else {
-      expression = new MethodInvocation(receiver, name, arguments)
-        ..fileOffset = fileOffset;
-    }
+    Expression expression = new DynamicInvocation(
+        DynamicAccessKind.Never, receiver, name, arguments)
+      ..fileOffset = fileOffset;
     return createNullAwareExpressionInferenceResult(
         const NeverType.nonNullable(),
         result.applyResult(expression),
@@ -2985,52 +2957,39 @@
         isImplicitCall: isImplicitCall);
     Expression? expression;
     String? localName;
-    if (useNewMethodInvocationEncoding) {
-      DartType inferredFunctionType = result.functionType;
-      if (result.isInapplicable) {
-        // This was a function invocation whose arguments didn't match
-        // the parameters.
-        expression = new FunctionInvocation(
-            FunctionAccessKind.Inapplicable, receiver, arguments,
-            functionType: null)
-          ..fileOffset = fileOffset;
-      } else if (receiver is VariableGet) {
-        VariableDeclaration variable = receiver.variable;
-        TreeNode? parent = variable.parent;
-        if (parent is FunctionDeclaration) {
-          assert(!identical(inferredFunctionType, unknownFunction),
-              "Unknown function type for local function invocation.");
-          localName = variable.name!;
-          expression = new LocalFunctionInvocation(variable, arguments,
-              functionType: inferredFunctionType as FunctionType)
-            ..fileOffset = receiver.fileOffset;
-        }
-      }
-      expression ??= new FunctionInvocation(
-          target.isNullableCallFunction
-              ? FunctionAccessKind.Nullable
-              : (identical(inferredFunctionType, unknownFunction)
-                  ? FunctionAccessKind.Function
-                  : FunctionAccessKind.FunctionType),
-          receiver,
-          arguments,
-          functionType: identical(inferredFunctionType, unknownFunction)
-              ? null
-              : inferredFunctionType as FunctionType)
+
+    DartType inferredFunctionType = result.functionType;
+    if (result.isInapplicable) {
+      // This was a function invocation whose arguments didn't match
+      // the parameters.
+      expression = new FunctionInvocation(
+          FunctionAccessKind.Inapplicable, receiver, arguments,
+          functionType: null)
         ..fileOffset = fileOffset;
-    } else {
-      if (receiver is VariableGet) {
-        VariableDeclaration variable = receiver.variable;
-        TreeNode? parent = variable.parent;
-        if (parent is FunctionDeclaration) {
-          // This is a local function invocation. Use the name in bounds
-          // checking below.
-          localName = variable.name!;
-        }
+    } else if (receiver is VariableGet) {
+      VariableDeclaration variable = receiver.variable;
+      TreeNode? parent = variable.parent;
+      if (parent is FunctionDeclaration) {
+        assert(!identical(inferredFunctionType, unknownFunction),
+            "Unknown function type for local function invocation.");
+        localName = variable.name!;
+        expression = new LocalFunctionInvocation(variable, arguments,
+            functionType: inferredFunctionType as FunctionType)
+          ..fileOffset = receiver.fileOffset;
       }
-      expression = new MethodInvocation(receiver, callName, arguments)
-        ..fileOffset = fileOffset;
     }
+    expression ??= new FunctionInvocation(
+        target.isNullableCallFunction
+            ? FunctionAccessKind.Nullable
+            : (identical(inferredFunctionType, unknownFunction)
+                ? FunctionAccessKind.Function
+                : FunctionAccessKind.FunctionType),
+        receiver,
+        arguments,
+        functionType: identical(inferredFunctionType, unknownFunction)
+            ? null
+            : inferredFunctionType as FunctionType)
+      ..fileOffset = fileOffset;
 
     _checkBoundsInFunctionInvocation(
         declaredFunctionType, localName, arguments, fileOffset);
@@ -3145,51 +3104,45 @@
         isSpecialCasedTernaryOperator: isSpecialCasedTernaryOperator);
 
     Expression expression;
-    if (useNewMethodInvocationEncoding) {
-      DartType inferredFunctionType = result.functionType;
-      if (target.isDynamic) {
-        // This was an Object member invocation whose arguments didn't match
-        // the parameters.
-        expression = new DynamicInvocation(
-            DynamicAccessKind.Dynamic, receiver, methodName, arguments)
-          ..fileOffset = fileOffset;
-      } else if (result.isInapplicable) {
-        // This was a method invocation whose arguments didn't match
-        // the parameters.
-        expression = new InstanceInvocation(
-            InstanceAccessKind.Inapplicable, receiver, methodName, arguments,
-            functionType: _computeFunctionTypeForArguments(
-                arguments, const InvalidType()),
-            interfaceTarget: method!)
-          ..fileOffset = fileOffset;
-      } else {
-        assert(
-            inferredFunctionType is FunctionType &&
-                !identical(unknownFunction, inferredFunctionType),
-            "No function type found for $receiver.$methodName ($target) on "
-            "$receiverType");
-        InstanceAccessKind kind;
-        switch (target.kind) {
-          case ObjectAccessTargetKind.instanceMember:
-            kind = InstanceAccessKind.Instance;
-            break;
-          case ObjectAccessTargetKind.nullableInstanceMember:
-            kind = InstanceAccessKind.Nullable;
-            break;
-          case ObjectAccessTargetKind.objectMember:
-            kind = InstanceAccessKind.Object;
-            break;
-          default:
-            throw new UnsupportedError('Unexpected target kind $target');
-        }
-        expression = new InstanceInvocation(
-            kind, receiver, methodName, arguments,
-            functionType: inferredFunctionType as FunctionType,
-            interfaceTarget: method!)
-          ..fileOffset = fileOffset;
-      }
+    DartType inferredFunctionType = result.functionType;
+    if (target.isDynamic) {
+      // This was an Object member invocation whose arguments didn't match
+      // the parameters.
+      expression = new DynamicInvocation(
+          DynamicAccessKind.Dynamic, receiver, methodName, arguments)
+        ..fileOffset = fileOffset;
+    } else if (result.isInapplicable) {
+      // This was a method invocation whose arguments didn't match
+      // the parameters.
+      expression = new InstanceInvocation(
+          InstanceAccessKind.Inapplicable, receiver, methodName, arguments,
+          functionType:
+              _computeFunctionTypeForArguments(arguments, const InvalidType()),
+          interfaceTarget: method!)
+        ..fileOffset = fileOffset;
     } else {
-      expression = new MethodInvocation(receiver, methodName, arguments, method)
+      assert(
+          inferredFunctionType is FunctionType &&
+              !identical(unknownFunction, inferredFunctionType),
+          "No function type found for $receiver.$methodName ($target) on "
+          "$receiverType");
+      InstanceAccessKind kind;
+      switch (target.kind) {
+        case ObjectAccessTargetKind.instanceMember:
+          kind = InstanceAccessKind.Instance;
+          break;
+        case ObjectAccessTargetKind.nullableInstanceMember:
+          kind = InstanceAccessKind.Nullable;
+          break;
+        case ObjectAccessTargetKind.objectMember:
+          kind = InstanceAccessKind.Object;
+          break;
+        default:
+          throw new UnsupportedError('Unexpected target kind $target');
+      }
+      expression = new InstanceInvocation(kind, receiver, methodName, arguments,
+          functionType: inferredFunctionType as FunctionType,
+          interfaceTarget: method!)
         ..fileOffset = fileOffset;
     }
     Expression replacement;
@@ -3307,30 +3260,24 @@
     Name originalName = getter!.name;
     Expression originalReceiver = receiver;
     Member originalTarget = getter;
-    Expression originalPropertyGet;
-    if (useNewMethodInvocationEncoding) {
-      InstanceAccessKind kind;
-      switch (target.kind) {
-        case ObjectAccessTargetKind.instanceMember:
-          kind = InstanceAccessKind.Instance;
-          break;
-        case ObjectAccessTargetKind.nullableInstanceMember:
-          kind = InstanceAccessKind.Nullable;
-          break;
-        case ObjectAccessTargetKind.objectMember:
-          kind = InstanceAccessKind.Object;
-          break;
-        default:
-          throw new UnsupportedError('Unexpected target kind $target');
-      }
-      originalPropertyGet = new InstanceGet(
-          kind, originalReceiver, originalName,
-          resultType: calleeType, interfaceTarget: originalTarget)
-        ..fileOffset = fileOffset;
-    } else {
-      originalPropertyGet = new PropertyGet(receiver, getter.name, getter)
-        ..fileOffset = fileOffset;
+    InstanceAccessKind kind;
+    switch (target.kind) {
+      case ObjectAccessTargetKind.instanceMember:
+        kind = InstanceAccessKind.Instance;
+        break;
+      case ObjectAccessTargetKind.nullableInstanceMember:
+        kind = InstanceAccessKind.Nullable;
+        break;
+      case ObjectAccessTargetKind.objectMember:
+        kind = InstanceAccessKind.Object;
+        break;
+      default:
+        throw new UnsupportedError('Unexpected target kind $target');
     }
+    InstanceGet originalPropertyGet = new InstanceGet(
+        kind, originalReceiver, originalName,
+        resultType: calleeType, interfaceTarget: originalTarget)
+      ..fileOffset = fileOffset;
     Expression propertyGet = originalPropertyGet;
     if (calleeType is! DynamicType &&
         receiver is! ThisExpression &&
@@ -3395,45 +3342,29 @@
       // TODO(johnniwinther): Remove this when dart2js/ddc supports explicit
       //  getter calls.
       Expression nullAwareAction = invocationResult.nullAwareAction;
-      if (nullAwareAction is MethodInvocation &&
+      if (nullAwareAction is InstanceInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new MethodInvocation(originalReceiver, originalName,
-                nullAwareAction.arguments, originalTarget)
-              ..fileOffset = nullAwareAction.fileOffset);
-      } else if (nullAwareAction is InstanceInvocation &&
-          nullAwareAction.receiver == originalPropertyGet) {
-        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
-        // used and [originalPropertyGet] can be an [InstanceGet].
-        InstanceGet instanceGet = originalPropertyGet as InstanceGet;
-        invocationResult = new ExpressionInferenceResult(
-            invocationResult.inferredType,
-            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
-                originalName, nullAwareAction.arguments,
+            new InstanceGetterInvocation(originalPropertyGet.kind,
+                originalReceiver, originalName, nullAwareAction.arguments,
                 interfaceTarget: originalTarget,
                 functionType: nullAwareAction.functionType)
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is DynamicInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
-        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
-        // used and [originalPropertyGet] can be an [InstanceGet].
-        InstanceGet instanceGet = originalPropertyGet as InstanceGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
-                originalName, nullAwareAction.arguments,
+            new InstanceGetterInvocation(originalPropertyGet.kind,
+                originalReceiver, originalName, nullAwareAction.arguments,
                 interfaceTarget: originalTarget, functionType: null)
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is FunctionInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
-        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
-        // used and [originalPropertyGet] can be an [InstanceGet].
-        InstanceGet instanceGet = originalPropertyGet as InstanceGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
-                originalName, nullAwareAction.arguments,
+            new InstanceGetterInvocation(originalPropertyGet.kind,
+                originalReceiver, originalName, nullAwareAction.arguments,
                 interfaceTarget: originalTarget,
                 functionType: nullAwareAction.functionType)
               ..fileOffset = nullAwareAction.fileOffset);
@@ -3511,31 +3442,24 @@
     Name originalName = field.name;
     Expression originalReceiver = receiver;
     Member originalTarget = field;
-    Expression originalPropertyGet;
-    if (useNewMethodInvocationEncoding) {
-      InstanceAccessKind kind;
-      switch (target.kind) {
-        case ObjectAccessTargetKind.instanceMember:
-          kind = InstanceAccessKind.Instance;
-          break;
-        case ObjectAccessTargetKind.nullableInstanceMember:
-          kind = InstanceAccessKind.Nullable;
-          break;
-        case ObjectAccessTargetKind.objectMember:
-          kind = InstanceAccessKind.Object;
-          break;
-        default:
-          throw new UnsupportedError('Unexpected target kind $target');
-      }
-      originalPropertyGet = new InstanceGet(
-          kind, originalReceiver, originalName,
-          resultType: calleeType, interfaceTarget: originalTarget)
-        ..fileOffset = fileOffset;
-    } else {
-      originalPropertyGet =
-          new PropertyGet(originalReceiver, originalName, originalTarget)
-            ..fileOffset = fileOffset;
+    InstanceAccessKind kind;
+    switch (target.kind) {
+      case ObjectAccessTargetKind.instanceMember:
+        kind = InstanceAccessKind.Instance;
+        break;
+      case ObjectAccessTargetKind.nullableInstanceMember:
+        kind = InstanceAccessKind.Nullable;
+        break;
+      case ObjectAccessTargetKind.objectMember:
+        kind = InstanceAccessKind.Object;
+        break;
+      default:
+        throw new UnsupportedError('Unexpected target kind $target');
     }
+    InstanceGet originalPropertyGet = new InstanceGet(
+        kind, originalReceiver, originalName,
+        resultType: calleeType, interfaceTarget: originalTarget)
+      ..fileOffset = fileOffset;
     flowAnalysis.propertyGet(originalPropertyGet, originalReceiver,
         originalName.text, originalTarget, calleeType);
     Expression propertyGet = originalPropertyGet;
@@ -3606,45 +3530,29 @@
       // TODO(johnniwinther): Remove this when dart2js/ddc supports explicit
       //  getter calls.
       Expression nullAwareAction = invocationResult.nullAwareAction;
-      if (nullAwareAction is MethodInvocation &&
+      if (nullAwareAction is InstanceInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new MethodInvocation(originalReceiver, originalName,
-                nullAwareAction.arguments, originalTarget)
-              ..fileOffset = nullAwareAction.fileOffset);
-      } else if (nullAwareAction is InstanceInvocation &&
-          nullAwareAction.receiver == originalPropertyGet) {
-        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
-        // used and [originalPropertyGet] can be an [InstanceGet].
-        InstanceGet instanceGet = originalPropertyGet as InstanceGet;
-        invocationResult = new ExpressionInferenceResult(
-            invocationResult.inferredType,
-            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
-                originalName, nullAwareAction.arguments,
+            new InstanceGetterInvocation(originalPropertyGet.kind,
+                originalReceiver, originalName, nullAwareAction.arguments,
                 interfaceTarget: originalTarget,
                 functionType: nullAwareAction.functionType)
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is DynamicInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
-        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
-        // used and [originalPropertyGet] can be an [InstanceGet].
-        InstanceGet instanceGet = originalPropertyGet as InstanceGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
-                originalName, nullAwareAction.arguments,
+            new InstanceGetterInvocation(originalPropertyGet.kind,
+                originalReceiver, originalName, nullAwareAction.arguments,
                 interfaceTarget: originalTarget, functionType: null)
               ..fileOffset = nullAwareAction.fileOffset);
       } else if (nullAwareAction is FunctionInvocation &&
           nullAwareAction.receiver == originalPropertyGet) {
-        // TODO(johnniwinther): Remove this when [MethodInvocation] is no longer
-        // used and [originalPropertyGet] can be an [InstanceGet].
-        InstanceGet instanceGet = originalPropertyGet as InstanceGet;
         invocationResult = new ExpressionInferenceResult(
             invocationResult.inferredType,
-            new InstanceGetterInvocation(instanceGet.kind, originalReceiver,
-                originalName, nullAwareAction.arguments,
+            new InstanceGetterInvocation(originalPropertyGet.kind,
+                originalReceiver, originalName, nullAwareAction.arguments,
                 interfaceTarget: originalTarget,
                 functionType: nullAwareAction.functionType)
               ..fileOffset = nullAwareAction.fileOffset);
@@ -4486,18 +4394,7 @@
   /// the interface target of the created method invocation.
   Expression createEqualsNull(
       int fileOffset, Expression left, Member equalsMember) {
-    if (useNewMethodInvocationEncoding) {
-      return new EqualsNull(left)..fileOffset = fileOffset;
-    } else {
-      return new MethodInvocation(
-          left,
-          equalsName,
-          new Arguments(
-              <Expression>[new NullLiteral()..fileOffset = fileOffset])
-            ..fileOffset = fileOffset)
-        ..fileOffset = fileOffset
-        ..interfaceTarget = equalsMember;
-    }
+    return new EqualsNull(left)..fileOffset = fileOffset;
   }
 }
 
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index 50cf52f..13229aa 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -208,24 +208,6 @@
   }
 
   @override
-  visitMethodInvocation(MethodInvocation node) {
-    TreeNode receiver = node.receiver;
-    if (receiver is VariableGet &&
-        receiver.variable.parent is FunctionDeclaration) {
-      // This is an invocation of a named local function.
-      computeForNode(node, createInvokeId(node.receiver));
-      node.arguments.accept(this);
-    } else if (node.name.text == '==' &&
-        receiver is VariableGet &&
-        receiver.variable.name == null) {
-      // This is a desugared `?.`.
-    } else {
-      _visitInvocation(node, node.name);
-      super.visitMethodInvocation(node);
-    }
-  }
-
-  @override
   visitDynamicInvocation(DynamicInvocation node) {
     _visitInvocation(node, node.name);
     super.visitDynamicInvocation(node);
@@ -278,12 +260,6 @@
   }
 
   @override
-  visitPropertyGet(PropertyGet node) {
-    computeForNode(node, computeDefaultNodeId(node));
-    super.visitPropertyGet(node);
-  }
-
-  @override
   visitDynamicGet(DynamicGet node) {
     computeForNode(node, computeDefaultNodeId(node));
     super.visitDynamicGet(node);
@@ -344,12 +320,6 @@
   }
 
   @override
-  visitPropertySet(PropertySet node) {
-    computeForNode(node, createUpdateId(node));
-    super.visitPropertySet(node);
-  }
-
-  @override
   visitDynamicSet(DynamicSet node) {
     computeForNode(node, createUpdateId(node));
     super.visitDynamicSet(node);
@@ -529,11 +499,8 @@
   visitThisExpression(ThisExpression node) {
     TreeNode parent = node.parent!;
     if (node.fileOffset == TreeNode.noOffset ||
-        (parent is PropertyGet ||
-                parent is InstanceGet ||
-                parent is PropertySet ||
+        (parent is InstanceGet ||
                 parent is InstanceSet ||
-                parent is MethodInvocation ||
                 parent is InstanceInvocation) &&
             parent.fileOffset == node.fileOffset) {
       // Skip implicit this expressions.
diff --git a/pkg/front_end/test/comments_on_certain_arguments_tool.dart b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
index 56ddf2e..4ad6562 100644
--- a/pkg/front_end/test/comments_on_certain_arguments_tool.dart
+++ b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
@@ -181,13 +181,6 @@
     super.visitProcedure(node);
   }
 
-  void visitMethodInvocation(MethodInvocation node) {
-    super.visitMethodInvocation(node);
-    if (node.interfaceTargetReference?.node != null) {
-      note(node.interfaceTargetReference?.node, node.arguments, node);
-    }
-  }
-
   void visitSuperMethodInvocation(SuperMethodInvocation node) {
     super.visitSuperMethodInvocation(node);
     note(node.interfaceTargetReference.node, node.arguments, node);
@@ -226,8 +219,15 @@
       } else if (arguments.positional[i] is ListLiteral) {
         ListLiteral literal = arguments.positional[i];
         if (literal.expressions.isEmpty) wantComment = true;
-      } else if (arguments.positional[i] is MethodInvocation) {
-        MethodInvocation methodInvocation = arguments.positional[i];
+      } else if (arguments.positional[i] is InstanceInvocation) {
+        InstanceInvocation methodInvocation = arguments.positional[i];
+        if (methodInvocation.receiver is NullLiteral ||
+            methodInvocation.receiver is IntLiteral ||
+            methodInvocation.receiver is BoolLiteral) {
+          wantComment = true;
+        }
+      } else if (arguments.positional[i] is DynamicInvocation) {
+        DynamicInvocation methodInvocation = arguments.positional[i];
         if (methodInvocation.receiver is NullLiteral ||
             methodInvocation.receiver is IntLiteral ||
             methodInvocation.receiver is BoolLiteral) {
diff --git a/pkg/front_end/test/static_types/analysis_helper.dart b/pkg/front_end/test/static_types/analysis_helper.dart
index 3ae2d5b..2091112 100644
--- a/pkg/front_end/test/static_types/analysis_helper.dart
+++ b/pkg/front_end/test/static_types/analysis_helper.dart
@@ -282,33 +282,6 @@
   }
 
   @override
-  void visitPropertyGet(PropertyGet node) {
-    DartType receiverType = node.receiver.getStaticType(staticTypeContext);
-    if (receiverType is DynamicType && node.interfaceTarget == null) {
-      registerError(node, "Dynamic access of '${node.name}'.");
-    }
-    super.visitPropertyGet(node);
-  }
-
-  @override
-  void visitPropertySet(PropertySet node) {
-    DartType receiverType = node.receiver.getStaticType(staticTypeContext);
-    if (receiverType is DynamicType) {
-      registerError(node, "Dynamic update to '${node.name}'.");
-    }
-    super.visitPropertySet(node);
-  }
-
-  @override
-  void visitMethodInvocation(MethodInvocation node) {
-    DartType receiverType = node.receiver.getStaticType(staticTypeContext);
-    if (receiverType is DynamicType && node.interfaceTarget == null) {
-      registerError(node, "Dynamic invocation of '${node.name}'.");
-    }
-    super.visitMethodInvocation(node);
-  }
-
-  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     if (checkReturnTypes && node.function.returnType is DynamicType) {
       registerError(node, "Dynamic return type");
diff --git a/pkg/front_end/test/text_representation/empty_reference_test.dart b/pkg/front_end/test/text_representation/empty_reference_test.dart
index a33bd6b..0e36da8 100644
--- a/pkg/front_end/test/text_representation/empty_reference_test.dart
+++ b/pkg/front_end/test/text_representation/empty_reference_test.dart
@@ -83,15 +83,15 @@
 }
 
 void testMembers() {
-  testExpression(new PropertyGet(new IntLiteral(0), new Name('foo')), '''
-0.foo''');
   testExpression(new StaticGet.byReference(null), '''
 <missing-member-reference>''');
 
   Reference unlinkedMemberName = new Reference();
   testExpression(
-      new PropertyGet.byReference(
-          new IntLiteral(0), new Name('foo'), unlinkedMemberName),
+      new InstanceGet.byReference(
+          InstanceAccessKind.Instance, new IntLiteral(0), new Name('foo'),
+          interfaceTargetReference: unlinkedMemberName,
+          resultType: const DynamicType()),
       '''
 0.foo''');
   testExpression(new StaticGet.byReference(unlinkedMemberName), '''
@@ -100,8 +100,10 @@
   CanonicalName root = new CanonicalName.root();
   Reference rootReference = new Reference()..canonicalName = root;
   testExpression(
-      new PropertyGet.byReference(
-          new IntLiteral(0), new Name('foo'), rootReference),
+      new InstanceGet.byReference(
+          InstanceAccessKind.Instance, new IntLiteral(0), new Name('foo'),
+          interfaceTargetReference: rootReference,
+          resultType: const DynamicType()),
       '''
 0.foo''');
   testExpression(new StaticGet.byReference(rootReference), '''
@@ -110,8 +112,10 @@
   CanonicalName library = root.getChild('library');
   Reference libraryReference = new Reference()..canonicalName = library;
   testExpression(
-      new PropertyGet.byReference(
-          new IntLiteral(0), new Name('foo'), libraryReference),
+      new InstanceGet.byReference(
+          InstanceAccessKind.Instance, new IntLiteral(0), new Name('foo'),
+          interfaceTargetReference: libraryReference,
+          resultType: const DynamicType()),
       '''
 0.foo''');
   testExpression(new StaticGet.byReference(libraryReference), '''
@@ -121,8 +125,10 @@
   Reference topLevelMemberNameReference = new Reference()
     ..canonicalName = topLevelMemberName;
   testExpression(
-      new PropertyGet.byReference(
-          new IntLiteral(0), new Name('foo'), topLevelMemberNameReference),
+      new InstanceGet.byReference(
+          InstanceAccessKind.Instance, new IntLiteral(0), new Name('foo'),
+          interfaceTargetReference: topLevelMemberNameReference,
+          resultType: const DynamicType()),
       '''
 0.foo''');
   testExpression(new StaticGet.byReference(topLevelMemberNameReference), '''
@@ -132,8 +138,10 @@
   CanonicalName className = library.getChild('Class');
   Reference classNameReference = new Reference()..canonicalName = className;
   testExpression(
-      new PropertyGet.byReference(
-          new IntLiteral(0), new Name('foo'), classNameReference),
+      new InstanceGet.byReference(
+          InstanceAccessKind.Instance, new IntLiteral(0), new Name('foo'),
+          interfaceTargetReference: classNameReference,
+          resultType: const DynamicType()),
       '''
 0.foo''');
   testExpression(new StaticGet.byReference(classNameReference), '''
@@ -144,8 +152,10 @@
   Reference classMemberNameReference = new Reference()
     ..canonicalName = classMemberName;
   testExpression(
-      new PropertyGet.byReference(
-          new IntLiteral(0), new Name('foo'), classMemberNameReference),
+      new InstanceGet.byReference(
+          InstanceAccessKind.Instance, new IntLiteral(0), new Name('foo'),
+          interfaceTargetReference: classMemberNameReference,
+          resultType: const DynamicType()),
       '''
 0.foo''');
   testExpression(new StaticGet.byReference(classMemberNameReference), '''
diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
index a88f79a..4f17a6e 100644
--- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
+++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart
@@ -46,6 +46,7 @@
   _testIntLiterals();
   _testInternalMethodInvocation();
   _testInternalPropertyGet();
+  _testInternalPropertySet();
   _testExpressionInvocation();
   _testNamedFunctionExpressionJudgment();
   _testNullAwareMethodInvocation();
@@ -286,7 +287,7 @@
   testExpression(cascade, '''
 let final dynamic #0 = 0 in cascade {} => #0''');
 
-  cascade.addCascadeExpression(new PropertySet(
+  cascade.addCascadeExpression(new DynamicSet(DynamicAccessKind.Dynamic,
       new VariableGet(variable), new Name('foo'), new IntLiteral(1)));
   testExpression(cascade, '''
 let final dynamic #0 = 0 in cascade {
@@ -294,7 +295,7 @@
 } => #0''', limited: '''
 let final dynamic #0 = 0 in cascade { #0.foo = 1; } => #0''');
 
-  cascade.addCascadeExpression(new PropertySet(
+  cascade.addCascadeExpression(new DynamicSet(DynamicAccessKind.Dynamic,
       new VariableGet(variable), new Name('bar'), new IntLiteral(2)));
   testExpression(cascade, '''
 let final dynamic #0 = 0 in cascade {
@@ -403,6 +404,15 @@
 0.boz''');
 }
 
+void _testInternalPropertySet() {
+  testExpression(
+      new InternalPropertySet(
+          new IntLiteral(0), new Name('boz'), new IntLiteral(1),
+          forEffect: false, readOnlyReceiver: false),
+      '''
+0.boz = 1''');
+}
+
 void _testExpressionInvocation() {
   testExpression(
       new ExpressionInvocation(new IntLiteral(0), new ArgumentsImpl([])), '''
@@ -440,11 +450,17 @@
   testExpression(
       new NullAwareMethodInvocation(
           variable,
-          new MethodInvocation(new VariableGet(variable), new Name('foo'),
+          new DynamicInvocation(
+              DynamicAccessKind.Dynamic,
+              new VariableGet(variable),
+              new Name('foo'),
               new ArgumentsImpl([]))),
       '''
 0?.foo()''');
 
+  // TODO(johnniwinther): Add a test using InstanceInvocation instead of
+  // DynamicInvocation.
+
   // An unusual use of this node.
   testExpression(
       new NullAwareMethodInvocation(variable,
@@ -468,7 +484,10 @@
   testExpression(
       new NullAwarePropertyGet(
           variable,
-          new MethodInvocation(new VariableGet(variable), new Name('foo'),
+          new DynamicInvocation(
+              DynamicAccessKind.Dynamic,
+              new VariableGet(variable),
+              new Name('foo'),
               new ArgumentsImpl([]))),
       '''
 let final dynamic #0 = 0 in null-aware #0.foo()''');
@@ -481,15 +500,20 @@
   testExpression(
       new NullAwarePropertySet(
           variable,
-          new PropertySet(
-              new VariableGet(variable), new Name('foo'), new IntLiteral(1))),
+          new DynamicSet(DynamicAccessKind.Dynamic, new VariableGet(variable),
+              new Name('foo'), new IntLiteral(1))),
       '''
 0?.foo = 1''');
 
+  // TODO(johnniwinther): Add a test using InstanceSet instead of DynamicSet.
+
   testExpression(
       new NullAwarePropertySet(
           variable,
-          new MethodInvocation(new VariableGet(variable), new Name('foo'),
+          new DynamicInvocation(
+              DynamicAccessKind.Dynamic,
+              new VariableGet(variable),
+              new Name('foo'),
               new ArgumentsImpl([]))),
       '''
 let final dynamic #0 = 0 in null-aware #0.foo()''');
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index a2f3687..e013be5 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -147,7 +147,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 68;
+  UInt32 formatVersion = 69;
   Byte[10] shortSdkHash;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
@@ -584,25 +584,6 @@
   // Equivalent to VariableSet with index N.
 }
 
-type PropertyGet extends Expression {
-  Byte tag = 22;
-  FileOffset fileOffset;
-  Expression receiver;
-  Name name;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
-}
-
-type PropertySet extends Expression {
-  Byte tag = 23;
-  FileOffset fileOffset;
-  Expression receiver;
-  Name name;
-  Expression value;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
-}
-
 type SuperPropertyGet extends Expression {
   Byte tag = 24;
   FileOffset fileOffset;
@@ -740,17 +721,6 @@
   Expression value;
 }
 
-type MethodInvocation extends Expression {
-  Byte tag = 28;
-  Byte flags (isInvariant, isBoundsSafe);
-  FileOffset fileOffset;
-  Expression receiver;
-  Name name;
-  Arguments arguments;
-  MemberReference interfaceTarget; // May be NullReference.
-  MemberReference interfaceTargetOrigin; // May be NullReference.
-}
-
 type InstanceInvocation extends Expression {
   Byte tag = 120;
   Byte kind; // Index into InstanceAccessKind above.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index d7c72c7..0ac7cb7 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -4227,96 +4227,6 @@
   }
 }
 
-/// Expression of form `x.field`.
-///
-/// This may invoke a getter, read a field, or tear off a method.
-class PropertyGet extends Expression {
-  Expression receiver;
-  Name name;
-
-  Reference? interfaceTargetReference;
-
-  PropertyGet(Expression receiver, Name name, [Member? interfaceTarget])
-      : this.byReference(
-            receiver, name, getMemberReferenceGetter(interfaceTarget));
-
-  PropertyGet.byReference(
-      this.receiver, this.name, this.interfaceTargetReference) {
-    receiver.parent = this;
-  }
-
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
-
-  void set interfaceTarget(Member? member) {
-    interfaceTargetReference = getMemberReferenceGetter(member);
-  }
-
-  @override
-  DartType getStaticTypeInternal(StaticTypeContext context) {
-    Member? interfaceTarget = this.interfaceTarget;
-    if (interfaceTarget != null) {
-      Class superclass = interfaceTarget.enclosingClass!;
-      InterfaceType receiverType =
-          receiver.getStaticTypeAsInstanceOf(superclass, context);
-      return Substitution.fromInterfaceType(receiverType)
-          .substituteType(interfaceTarget.getterType);
-    }
-    // Treat the properties of Object specially.
-    String nameString = name.text;
-    if (nameString == 'hashCode') {
-      return context.typeEnvironment.coreTypes.intRawType(context.nonNullable);
-    } else if (nameString == 'runtimeType') {
-      return context.typeEnvironment.coreTypes.typeRawType(context.nonNullable);
-    }
-    return const DynamicType();
-  }
-
-  @override
-  R accept<R>(ExpressionVisitor<R> v) => v.visitPropertyGet(this);
-
-  @override
-  R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
-      v.visitPropertyGet(this, arg);
-
-  @override
-  void visitChildren(Visitor v) {
-    receiver.accept(v);
-    interfaceTarget?.acceptReference(v);
-    name.accept(v);
-  }
-
-  @override
-  void transformChildren(Transformer v) {
-    // ignore: unnecessary_null_comparison
-    if (receiver != null) {
-      receiver = v.transform(receiver);
-      receiver.parent = this;
-    }
-  }
-
-  @override
-  void transformOrRemoveChildren(RemovingTransformer v) {
-    // ignore: unnecessary_null_comparison
-    if (receiver != null) {
-      receiver = v.transform(receiver);
-      receiver.parent = this;
-    }
-  }
-
-  @override
-  String toString() {
-    return "PropertyGet(${toStringInternal()})";
-  }
-
-  @override
-  void toTextInternal(AstPrinter printer) {
-    printer.writeExpression(receiver,
-        minimumPrecedence: astToText.Precedence.PRIMARY);
-    printer.write('.');
-    printer.writeInterfaceMemberName(interfaceTargetReference, name);
-  }
-}
-
 class DynamicSet extends Expression {
   final DynamicAccessKind kind;
   Expression receiver;
@@ -4484,98 +4394,6 @@
   }
 }
 
-/// Expression of form `x.field = value`.
-///
-/// This may invoke a setter or assign a field.
-///
-/// Evaluates to the value of [value].
-class PropertySet extends Expression {
-  Expression receiver;
-  Name name;
-  Expression value;
-
-  Reference? interfaceTargetReference;
-
-  PropertySet(Expression receiver, Name name, Expression value,
-      [Member? interfaceTarget])
-      : this.byReference(
-            receiver, name, value, getMemberReferenceSetter(interfaceTarget));
-
-  PropertySet.byReference(
-      this.receiver, this.name, this.value, this.interfaceTargetReference) {
-    receiver.parent = this;
-    value.parent = this;
-  }
-
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
-
-  void set interfaceTarget(Member? member) {
-    interfaceTargetReference = getMemberReferenceSetter(member);
-  }
-
-  @override
-  DartType getStaticTypeInternal(StaticTypeContext context) =>
-      value.getStaticType(context);
-
-  @override
-  R accept<R>(ExpressionVisitor<R> v) => v.visitPropertySet(this);
-
-  @override
-  R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
-      v.visitPropertySet(this, arg);
-
-  @override
-  void visitChildren(Visitor v) {
-    receiver.accept(v);
-    interfaceTarget?.acceptReference(v);
-    name.accept(v);
-    value.accept(v);
-  }
-
-  @override
-  void transformChildren(Transformer v) {
-    // ignore: unnecessary_null_comparison
-    if (receiver != null) {
-      receiver = v.transform(receiver);
-      receiver.parent = this;
-    }
-    // ignore: unnecessary_null_comparison
-    if (value != null) {
-      value = v.transform(value);
-      value.parent = this;
-    }
-  }
-
-  @override
-  void transformOrRemoveChildren(RemovingTransformer v) {
-    // ignore: unnecessary_null_comparison
-    if (receiver != null) {
-      receiver = v.transform(receiver);
-      receiver.parent = this;
-    }
-    // ignore: unnecessary_null_comparison
-    if (value != null) {
-      value = v.transform(value);
-      value.parent = this;
-    }
-  }
-
-  @override
-  String toString() {
-    return "PropertySet(${toStringInternal()})";
-  }
-
-  @override
-  void toTextInternal(AstPrinter printer) {
-    printer.writeExpression(receiver,
-        minimumPrecedence: astToText.Precedence.PRIMARY);
-    printer.write('.');
-    printer.writeInterfaceMemberName(interfaceTargetReference, name);
-    printer.write(' = ');
-    printer.writeExpression(value);
-  }
-}
-
 /// Expression of form `super.field`.
 ///
 /// This may invoke a getter, read a field, or tear off a method.
@@ -5948,210 +5766,6 @@
   }
 }
 
-/// Expression of form `x.foo(y)`.
-class MethodInvocation extends InstanceInvocationExpression {
-  // Must match serialized bit positions.
-  static const int FlagInvariant = 1 << 0;
-  static const int FlagBoundsSafe = 1 << 1;
-
-  @override
-  Expression receiver;
-
-  @override
-  Name name;
-
-  @override
-  Arguments arguments;
-
-  int flags = 0;
-
-  Reference? interfaceTargetReference;
-
-  MethodInvocation(Expression receiver, Name name, Arguments arguments,
-      [Member? interfaceTarget])
-      : this.byReference(
-            receiver,
-            name,
-            arguments,
-            // An invocation doesn't refer to the setter.
-            getMemberReferenceGetter(interfaceTarget));
-
-  MethodInvocation.byReference(
-      this.receiver, this.name, this.arguments, this.interfaceTargetReference) {
-    receiver.parent = this;
-    arguments.parent = this;
-  }
-
-  Member? get interfaceTarget => interfaceTargetReference?.asMember;
-
-  void set interfaceTarget(Member? target) {
-    // An invocation doesn't refer to the setter.
-    interfaceTargetReference = getMemberReferenceGetter(target);
-  }
-
-  /// If `true`, this call is known to be safe wrt. parameter covariance checks.
-  ///
-  /// This is for instance the case in code patterns like this
-  ///
-  ///     List<int> list = <int>[];
-  ///     list.add(0);
-  ///
-  /// where the `list` variable is known to hold a value of the same type as
-  /// the static type. In contrast the would not be the case in code patterns
-  /// like this
-  ///
-  ///     List<num> list = <double>[];
-  ///     list.add(0); // Runtime error `int` is not a subtype of `double`.
-  ///
-  bool get isInvariant => flags & FlagInvariant != 0;
-
-  void set isInvariant(bool value) {
-    flags = value ? (flags | FlagInvariant) : (flags & ~FlagInvariant);
-  }
-
-  /// If `true`, this call is known to be safe wrt. parameter covariance checks.
-  ///
-  /// This is for instance the case in code patterns like this
-  ///
-  ///     List list = new List.filled(2, 0);
-  ///     list[1] = 42;
-  ///
-  /// where the `list` is known to have a sufficient length for the update
-  /// in `list[1] = 42`.
-  bool get isBoundsSafe => flags & FlagBoundsSafe != 0;
-
-  void set isBoundsSafe(bool value) {
-    flags = value ? (flags | FlagBoundsSafe) : (flags & ~FlagBoundsSafe);
-  }
-
-  @override
-  DartType getStaticTypeInternal(StaticTypeContext context) {
-    Member? interfaceTarget = this.interfaceTarget;
-    if (interfaceTarget != null) {
-      if (interfaceTarget is Procedure &&
-          context.typeEnvironment
-              .isSpecialCasedBinaryOperator(interfaceTarget)) {
-        return context.typeEnvironment.getTypeOfSpecialCasedBinaryOperator(
-            receiver.getStaticType(context),
-            arguments.positional[0].getStaticType(context));
-      }
-      Class superclass = interfaceTarget.enclosingClass!;
-      InterfaceType receiverType =
-          receiver.getStaticTypeAsInstanceOf(superclass, context);
-      DartType getterType = Substitution.fromInterfaceType(receiverType)
-          .substituteType(interfaceTarget.getterType);
-      if (getterType is FunctionType) {
-        Substitution substitution;
-        if (getterType.typeParameters.length == arguments.types.length) {
-          substitution = Substitution.fromPairs(
-              getterType.typeParameters, arguments.types);
-        } else {
-          // TODO(johnniwinther): The front end should normalize the type
-          //  argument count or create an invalid expression in case of method
-          //  invocations with invalid type argument count.
-          substitution = Substitution.fromPairs(
-              getterType.typeParameters,
-              getterType.typeParameters
-                  .map((TypeParameter typeParameter) =>
-                      typeParameter.defaultType)
-                  .toList());
-        }
-        return substitution.substituteType(getterType.returnType);
-      }
-      // The front end currently do not replace a property call `o.foo()`, where
-      // `foo` is a field or getter, with a function call on the property,
-      // `o.foo.call()`, so we look up the call method explicitly here.
-      // TODO(johnniwinther): Remove this when the front end performs the
-      // correct replacement.
-      if (getterType is InterfaceType) {
-        Member? member = context.typeEnvironment
-            .getInterfaceMember(getterType.classNode, new Name('call'));
-        if (member != null) {
-          DartType callType = member.getterType;
-          if (callType is FunctionType) {
-            return Substitution.fromInterfaceType(getterType)
-                .substituteType(callType.returnType);
-          }
-        }
-      }
-      return const DynamicType();
-    }
-    if (name.text == 'call') {
-      DartType receiverType = receiver.getStaticType(context);
-      if (receiverType is FunctionType) {
-        if (receiverType.typeParameters.length != arguments.types.length) {
-          return const NeverType.nonNullable();
-        }
-        return Substitution.fromPairs(
-                receiverType.typeParameters, arguments.types)
-            .substituteType(receiverType.returnType);
-      }
-    }
-    if (name.text == '==') {
-      // We use this special case to simplify generation of '==' checks.
-      return context.typeEnvironment.coreTypes.boolRawType(context.nonNullable);
-    }
-    return const DynamicType();
-  }
-
-  @override
-  R accept<R>(ExpressionVisitor<R> v) => v.visitMethodInvocation(this);
-
-  @override
-  R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
-      v.visitMethodInvocation(this, arg);
-
-  @override
-  void visitChildren(Visitor v) {
-    receiver.accept(v);
-    interfaceTarget?.acceptReference(v);
-    name.accept(v);
-    arguments.accept(v);
-  }
-
-  @override
-  void transformChildren(Transformer v) {
-    // ignore: unnecessary_null_comparison
-    if (receiver != null) {
-      receiver = v.transform(receiver);
-      receiver.parent = this;
-    }
-    // ignore: unnecessary_null_comparison
-    if (arguments != null) {
-      arguments = v.transform(arguments);
-      arguments.parent = this;
-    }
-  }
-
-  @override
-  void transformOrRemoveChildren(RemovingTransformer v) {
-    // ignore: unnecessary_null_comparison
-    if (receiver != null) {
-      receiver = v.transform(receiver);
-      receiver.parent = this;
-    }
-    // ignore: unnecessary_null_comparison
-    if (arguments != null) {
-      arguments = v.transform(arguments);
-      arguments.parent = this;
-    }
-  }
-
-  @override
-  String toString() {
-    return "MethodInvocation(${toStringInternal()})";
-  }
-
-  @override
-  void toTextInternal(AstPrinter printer) {
-    printer.writeExpression(receiver,
-        minimumPrecedence: astToText.Precedence.PRIMARY);
-    printer.write('.');
-    printer.writeInterfaceMemberName(interfaceTargetReference, name);
-    printer.writeArguments(arguments);
-  }
-}
-
 /// Expression of form `super.foo(x)`.
 ///
 /// The provided arguments might not match the parameters of the target.
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 42c9b87..80b2979 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1960,16 +1960,12 @@
         return _readVariableSet();
       case Tag.SpecializedVariableSet:
         return _readSpecializedVariableSet(tagByte);
-      case Tag.PropertyGet:
-        return _readPropertyGet();
       case Tag.InstanceGet:
         return _readInstanceGet();
       case Tag.InstanceTearOff:
         return _readInstanceTearOff();
       case Tag.DynamicGet:
         return _readDynamicGet();
-      case Tag.PropertySet:
-        return _readPropertySet();
       case Tag.InstanceSet:
         return _readInstanceSet();
       case Tag.DynamicSet:
@@ -1990,8 +1986,6 @@
         return _readTypedefTearOff();
       case Tag.RedirectingFactoryTearOff:
         return _readRedirectingFactoryTearOff();
-      case Tag.MethodInvocation:
-        return _readMethodInvocation();
       case Tag.InstanceInvocation:
         return _readInstanceInvocation();
       case Tag.InstanceGetterInvocation:
@@ -2142,13 +2136,6 @@
       ..fileOffset = offset;
   }
 
-  Expression _readPropertyGet() {
-    int offset = readOffset();
-    return new PropertyGet.byReference(
-        readExpression(), readName(), readNullableInstanceMemberReference())
-      ..fileOffset = offset;
-  }
-
   Expression _readInstanceGet() {
     InstanceAccessKind kind = InstanceAccessKind.values[readByte()];
     int offset = readOffset();
@@ -2174,13 +2161,6 @@
       ..fileOffset = offset;
   }
 
-  Expression _readPropertySet() {
-    int offset = readOffset();
-    return new PropertySet.byReference(readExpression(), readName(),
-        readExpression(), readNullableInstanceMemberReference())
-      ..fileOffset = offset;
-  }
-
   Expression _readInstanceSet() {
     InstanceAccessKind kind = InstanceAccessKind.values[readByte()];
     int offset = readOffset();
@@ -2254,15 +2234,6 @@
       ..fileOffset = offset;
   }
 
-  Expression _readMethodInvocation() {
-    int flags = readByte();
-    int offset = readOffset();
-    return new MethodInvocation.byReference(readExpression(), readName(),
-        readArguments(), readNullableInstanceMemberReference())
-      ..fileOffset = offset
-      ..flags = flags;
-  }
-
   Expression _readInstanceInvocation() {
     InstanceAccessKind kind = InstanceAccessKind.values[readByte()];
     int flags = readByte();
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 1d243d9..aa211d3 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1529,15 +1529,6 @@
   }
 
   @override
-  void visitPropertyGet(PropertyGet node) {
-    writeByte(Tag.PropertyGet);
-    writeOffset(node.fileOffset);
-    writeNode(node.receiver);
-    writeName(node.name);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
-  }
-
-  @override
   void visitDynamicSet(DynamicSet node) {
     writeByte(Tag.DynamicSet);
     writeByte(node.kind.index);
@@ -1559,16 +1550,6 @@
   }
 
   @override
-  void visitPropertySet(PropertySet node) {
-    writeByte(Tag.PropertySet);
-    writeOffset(node.fileOffset);
-    writeNode(node.receiver);
-    writeName(node.name);
-    writeNode(node.value);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
-  }
-
-  @override
   void visitSuperPropertyGet(SuperPropertyGet node) {
     writeByte(Tag.SuperPropertyGet);
     writeOffset(node.fileOffset);
@@ -1708,17 +1689,6 @@
   }
 
   @override
-  void visitMethodInvocation(MethodInvocation node) {
-    writeByte(Tag.MethodInvocation);
-    writeByte(node.flags);
-    writeOffset(node.fileOffset);
-    writeNode(node.receiver);
-    writeName(node.name);
-    writeArgumentsNode(node.arguments);
-    writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
-  }
-
-  @override
   void visitSuperMethodInvocation(SuperMethodInvocation node) {
     writeByte(Tag.SuperMethodInvocation);
     writeOffset(node.fileOffset);
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 138be00..d578618 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -37,13 +37,10 @@
   static const int InvalidExpression = 19;
   static const int VariableGet = 20;
   static const int VariableSet = 21;
-  static const int PropertyGet = 22;
-  static const int PropertySet = 23;
   static const int SuperPropertyGet = 24;
   static const int SuperPropertySet = 25;
   static const int StaticGet = 26;
   static const int StaticSet = 27;
-  static const int MethodInvocation = 28;
   static const int SuperMethodInvocation = 29;
   static const int StaticInvocation = 30;
   static const int ConstructorInvocation = 31;
@@ -179,7 +176,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 68;
+  static const int BinaryFormatVersion = 69;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index a5bde19..9127088 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -164,16 +164,6 @@
     return new VariableSet(getVariableClone(node.variable)!, clone(node.value));
   }
 
-  visitPropertyGet(PropertyGet node) {
-    return new PropertyGet.byReference(
-        clone(node.receiver), node.name, node.interfaceTargetReference);
-  }
-
-  visitPropertySet(PropertySet node) {
-    return new PropertySet.byReference(clone(node.receiver), node.name,
-        clone(node.value), node.interfaceTargetReference);
-  }
-
   visitSuperPropertyGet(SuperPropertyGet node) {
     return new SuperPropertyGet.byReference(
         node.name, node.interfaceTargetReference);
@@ -192,12 +182,6 @@
     return new StaticSet.byReference(node.targetReference, clone(node.value));
   }
 
-  visitMethodInvocation(MethodInvocation node) {
-    return new MethodInvocation.byReference(clone(node.receiver), node.name,
-        clone(node.arguments), node.interfaceTargetReference)
-      ..flags = node.flags;
-  }
-
   visitSuperMethodInvocation(SuperMethodInvocation node) {
     return new SuperMethodInvocation.byReference(
         node.name, clone(node.arguments), node.interfaceTargetReference);
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index d3a6638..7470718 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -287,7 +287,6 @@
                 receiver == environment.coreTypes.functionNonNullableRawType ||
                 receiver is FunctionType) &&
             (where is InvocationExpression && where.name.text == 'call') ||
-        (where is PropertyGet && where.name.text == 'call') ||
         where is FunctionTearOff) {
       return;
     }
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 6885c8a..55a69cd 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -426,8 +426,6 @@
   /// with the accessed getter or field as the interface target.
   bool get supportsExplicitGetterCalls;
 
-  bool get supportsNewMethodInvocationEncoding;
-
   /// Builds an expression that instantiates an [Invocation] that can be passed
   /// to [noSuchMethod].
   Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
@@ -495,9 +493,6 @@
       !flags.forceNoExplicitGetterCallsForTesting;
 
   @override
-  bool get supportsNewMethodInvocationEncoding => true;
-
-  @override
   int get enabledConstructorTearOffLowerings =>
       flags.forceConstructorTearOffLoweringForTesting;
 
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 8a2af9b..eacfa1e 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1538,23 +1538,6 @@
     writeSymbol('null');
   }
 
-  visitMethodInvocation(MethodInvocation node) {
-    writeExpression(node.receiver, Precedence.PRIMARY);
-    writeSymbol('.');
-    writeInterfaceTarget(node.name, node.interfaceTargetReference);
-    List<String> flags = <String>[];
-    if (node.isInvariant) {
-      flags.add('Invariant');
-    }
-    if (node.isBoundsSafe) {
-      flags.add('BoundsSafe');
-    }
-    if (flags.isNotEmpty) {
-      write('{${flags.join(',')}}');
-    }
-    writeNode(node.arguments);
-  }
-
   visitSuperMethodInvocation(SuperMethodInvocation node) {
     writeWord('super');
     writeSymbol('.');
@@ -1985,12 +1968,6 @@
     writeSymbol('}');
   }
 
-  visitPropertyGet(PropertyGet node) {
-    writeExpression(node.receiver, Precedence.PRIMARY);
-    writeSymbol('.');
-    writeInterfaceTarget(node.name, node.interfaceTargetReference);
-  }
-
   visitDynamicSet(DynamicSet node) {
     writeExpression(node.receiver, Precedence.PRIMARY);
     _writeDynamicAccessKind(node.kind);
@@ -2008,14 +1985,6 @@
     writeExpression(node.value);
   }
 
-  visitPropertySet(PropertySet node) {
-    writeExpression(node.receiver, Precedence.PRIMARY);
-    writeSymbol('.');
-    writeInterfaceTarget(node.name, node.interfaceTargetReference);
-    writeSpaced('=');
-    writeExpression(node.value);
-  }
-
   visitSuperPropertyGet(SuperPropertyGet node) {
     writeWord('super');
     writeSymbol('.');
@@ -2825,9 +2794,6 @@
   int visitInvalidExpression(InvalidExpression node) => CALLEE;
 
   @override
-  int visitMethodInvocation(MethodInvocation node) => CALLEE;
-
-  @override
   int visitInstanceInvocation(InstanceInvocation node) => CALLEE;
 
   @override
@@ -2931,9 +2897,6 @@
   int visitVariableSet(VariableSet node) => EXPRESSION;
 
   @override
-  int visitPropertyGet(PropertyGet node) => PRIMARY;
-
-  @override
   int visitInstanceGet(InstanceGet node) => PRIMARY;
 
   @override
@@ -2946,9 +2909,6 @@
   int visitFunctionTearOff(FunctionTearOff node) => PRIMARY;
 
   @override
-  int visitPropertySet(PropertySet node) => EXPRESSION;
-
-  @override
   int visitSuperPropertyGet(SuperPropertyGet node) => PRIMARY;
 
   @override
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 2c80120..5d740c4 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -70,8 +70,6 @@
 
   String visitLet(Let _) => "let";
 
-  String visitPropertyGet(PropertyGet _) => "get-prop";
-  String visitPropertySet(PropertySet _) => "set-prop";
   String visitInstanceGet(InstanceGet _) => "get-instance";
   String visitInstanceSet(InstanceSet _) => "set-instance";
   String visitDynamicGet(DynamicGet _) => "get-dynamic";
@@ -80,7 +78,6 @@
   String visitFunctionTearOff(FunctionTearOff _) => "tearoff-function";
   String visitSuperPropertyGet(SuperPropertyGet _) => "get-super";
   String visitSuperPropertySet(SuperPropertySet _) => "set-super";
-  String visitMethodInvocation(MethodInvocation _) => "invoke-method";
   String visitInstanceInvocation(InstanceInvocation _) => "invoke-instance";
   String visitInstanceGetterInvocation(InstanceGetterInvocation _) =>
       "invoke-instance-getter";
@@ -419,33 +416,6 @@
   return new Let(tuple.first, tuple.second);
 }
 
-TextSerializer<PropertyGet> propertyGetSerializer = new Wrapped(
-    unwrapPropertyGet,
-    wrapPropertyGet,
-    new Tuple2Serializer(expressionSerializer, nameSerializer));
-
-Tuple2<Expression, Name> unwrapPropertyGet(PropertyGet expression) {
-  return new Tuple2(expression.receiver, expression.name);
-}
-
-PropertyGet wrapPropertyGet(Tuple2<Expression, Name> tuple) {
-  return new PropertyGet(tuple.first, tuple.second);
-}
-
-TextSerializer<PropertySet> propertySetSerializer = new Wrapped(
-    unwrapPropertySet,
-    wrapPropertySet,
-    new Tuple3Serializer(
-        expressionSerializer, nameSerializer, expressionSerializer));
-
-Tuple3<Expression, Name, Expression> unwrapPropertySet(PropertySet expression) {
-  return new Tuple3(expression.receiver, expression.name, expression.value);
-}
-
-PropertySet wrapPropertySet(Tuple3<Expression, Name, Expression> tuple) {
-  return new PropertySet(tuple.first, tuple.second, tuple.third);
-}
-
 TextSerializer<InstanceGet> instanceGetSerializer = new Wrapped<
         Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>,
         InstanceGet>(
@@ -590,22 +560,6 @@
   return new SuperPropertySet(tuple.first, tuple.second, null);
 }
 
-TextSerializer<MethodInvocation> methodInvocationSerializer = new Wrapped(
-    unwrapMethodInvocation,
-    wrapMethodInvocation,
-    new Tuple3Serializer(
-        expressionSerializer, nameSerializer, argumentsSerializer));
-
-Tuple3<Expression, Name, Arguments> unwrapMethodInvocation(
-    MethodInvocation expression) {
-  return new Tuple3(expression.receiver, expression.name, expression.arguments);
-}
-
-MethodInvocation wrapMethodInvocation(
-    Tuple3<Expression, Name, Arguments> tuple) {
-  return new MethodInvocation(tuple.first, tuple.second, tuple.third);
-}
-
 const Map<InstanceAccessKind, String> instanceAccessKindToName = const {
   InstanceAccessKind.Instance: "instance",
   InstanceAccessKind.Object: "object",
@@ -2620,8 +2574,6 @@
     "map": mapLiteralSerializer,
     "const-map": constMapLiteralSerializer,
     "let": letSerializer,
-    "get-prop": propertyGetSerializer,
-    "set-prop": propertySetSerializer,
     "get-instance": instanceGetSerializer,
     "set-instance": instanceSetSerializer,
     "get-dynamic": dynamicGetSerializer,
@@ -2630,7 +2582,6 @@
     "tearoff-function": functionTearOffSerializer,
     "get-super": superPropertyGetSerializer,
     "set-super": superPropertySetSerializer,
-    "invoke-method": methodInvocationSerializer,
     "invoke-instance": instanceInvocationSerializer,
     "invoke-instance-getter": instanceGetterInvocationSerializer,
     "invoke-dynamic": dynamicInvocationSerializer,
diff --git a/pkg/kernel/lib/transformations/scanner.dart b/pkg/kernel/lib/transformations/scanner.dart
index d80aa65..18c7814 100644
--- a/pkg/kernel/lib/transformations/scanner.dart
+++ b/pkg/kernel/lib/transformations/scanner.dart
@@ -260,7 +260,7 @@
     return result;
   }
 
-  void visitMethodInvocation(MethodInvocation node) {
+  void visitInstanceInvocation(InstanceInvocation node) {
     if (predicate(node)) {
       _result!.targets[node] = next?.scan(node);
       // TODO: Update result.errors.
diff --git a/pkg/kernel/lib/transformations/value_class.dart b/pkg/kernel/lib/transformations/value_class.dart
index 014256c..61481e5 100644
--- a/pkg/kernel/lib/transformations/value_class.dart
+++ b/pkg/kernel/lib/transformations/value_class.dart
@@ -61,17 +61,14 @@
 }
 
 void transformComponent(Component node, CoreTypes coreTypes,
-    ClassHierarchy hierarchy, TypeEnvironment typeEnvironment,
-    {required bool useNewMethodInvocationEncoding}) {
+    ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
   ValueClassScanner scanner = new ValueClassScanner();
   ScanResult<Class, Null> valueClasses = scanner.scan(node);
   for (Class valueClass in valueClasses.targets.keys) {
-    transformValueClass(valueClass, coreTypes, hierarchy, typeEnvironment,
-        useNewMethodInvocationEncoding: useNewMethodInvocationEncoding);
+    transformValueClass(valueClass, coreTypes, hierarchy, typeEnvironment);
   }
 
-  treatCopyWithCallSites(node, coreTypes, typeEnvironment, hierarchy,
-      useNewMethodInvocationEncoding: useNewMethodInvocationEncoding);
+  treatCopyWithCallSites(node, coreTypes, typeEnvironment, hierarchy);
 
   for (Class valueClass in valueClasses.targets.keys) {
     removeValueClassAnnotation(valueClass);
@@ -79,8 +76,7 @@
 }
 
 void transformValueClass(Class cls, CoreTypes coreTypes,
-    ClassHierarchy hierarchy, TypeEnvironment typeEnvironment,
-    {required bool useNewMethodInvocationEncoding}) {
+    ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
   Constructor? syntheticConstructor = null;
   for (Constructor constructor in cls.constructors) {
     if (constructor.isSynthetic) {
@@ -93,12 +89,9 @@
   allVariablesList.sort((a, b) => a.name!.compareTo(b.name!));
 
   addConstructor(cls, coreTypes, syntheticConstructor!);
-  addEqualsOperator(cls, coreTypes, hierarchy, allVariablesList,
-      useNewMethodInvocationEncoding: useNewMethodInvocationEncoding);
-  addHashCode(cls, coreTypes, hierarchy, allVariablesList,
-      useNewMethodInvocationEncoding: useNewMethodInvocationEncoding);
-  addToString(cls, coreTypes, hierarchy, allVariablesList,
-      useNewMethodInvocationEncoding: useNewMethodInvocationEncoding);
+  addEqualsOperator(cls, coreTypes, hierarchy, allVariablesList);
+  addHashCode(cls, coreTypes, hierarchy, allVariablesList);
+  addToString(cls, coreTypes, hierarchy, allVariablesList);
   addCopyWith(cls, coreTypes, hierarchy, allVariablesList, syntheticConstructor,
       typeEnvironment);
 }
@@ -140,8 +133,7 @@
 }
 
 void addEqualsOperator(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
-    List<VariableDeclaration> allVariablesList,
-    {required bool useNewMethodInvocationEncoding}) {
+    List<VariableDeclaration> allVariablesList) {
   List<VariableDeclaration> allVariables = allVariablesList.toList();
   for (Procedure procedure in cls.procedures) {
     if (procedure.kind == ProcedureKind.Operator &&
@@ -178,16 +170,10 @@
           ReturnStatement(allVariables
               .map((f) => _createEquals(
                   _createGet(ThisExpression(), Name(f.name!),
-                      interfaceTarget: targets[f],
-                      useNewMethodInvocationEncoding:
-                          useNewMethodInvocationEncoding),
+                      interfaceTarget: targets[f]),
                   _createGet(VariableGet(other, myType), Name(f.name!),
-                      interfaceTarget: targets[f],
-                      useNewMethodInvocationEncoding:
-                          useNewMethodInvocationEncoding),
-                  interfaceTarget: targetsEquals[f] as Procedure,
-                  useNewMethodInvocationEncoding:
-                      useNewMethodInvocationEncoding))
+                      interfaceTarget: targets[f]),
+                  interfaceTarget: targetsEquals[f] as Procedure))
               .fold(
                   IsExpression(VariableGet(other), myType),
                   (previousValue, element) => LogicalExpression(
@@ -200,8 +186,7 @@
 }
 
 void addHashCode(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
-    List<VariableDeclaration> allVariablesList,
-    {required bool useNewMethodInvocationEncoding}) {
+    List<VariableDeclaration> allVariablesList) {
   List<VariableDeclaration> allVariables = allVariablesList.toList();
   for (Procedure procedure in cls.procedures) {
     if (procedure.kind == ProcedureKind.Getter &&
@@ -255,13 +240,9 @@
                 allVariables
                     .map((f) => (_createGet(
                         _createGet(ThisExpression(), Name(f.name!),
-                            interfaceTarget: targets[f],
-                            useNewMethodInvocationEncoding:
-                                useNewMethodInvocationEncoding),
+                            interfaceTarget: targets[f]),
                         Name("hashCode"),
-                        interfaceTarget: targetsHashcode[f],
-                        useNewMethodInvocationEncoding:
-                            useNewMethodInvocationEncoding)))
+                        interfaceTarget: targetsHashcode[f])))
                     .fold(
                         _createGet(
                             StringLiteral(
@@ -269,9 +250,7 @@
                                     cls.name),
                             Name("hashCode"),
                             interfaceTarget: hierarchy.getInterfaceMember(
-                                coreTypes.stringClass, Name("hashCode")),
-                            useNewMethodInvocationEncoding:
-                                useNewMethodInvocationEncoding),
+                                coreTypes.stringClass, Name("hashCode"))),
                         (previousValue, element) => StaticInvocation(
                             hashCombine!, Arguments([previousValue, element])))
               ]))),
@@ -281,8 +260,7 @@
 }
 
 void addToString(Class cls, CoreTypes coreTypes, ClassHierarchy hierarchy,
-    List<VariableDeclaration> allVariablesList,
-    {required bool useNewMethodInvocationEncoding}) {
+    List<VariableDeclaration> allVariablesList) {
   List<Expression> wording = [StringLiteral("${cls.name}(")];
 
   for (VariableDeclaration variable in allVariablesList) {
@@ -296,12 +274,10 @@
         Name("toString")) as Procedure;
     wording.add(_createInvocation(
         _createGet(ThisExpression(), Name(variable.name!),
-            interfaceTarget: variableTarget,
-            useNewMethodInvocationEncoding: useNewMethodInvocationEncoding),
+            interfaceTarget: variableTarget),
         Name("toString"),
         Arguments([]),
-        interfaceTarget: toStringTarget,
-        useNewMethodInvocationEncoding: useNewMethodInvocationEncoding));
+        interfaceTarget: toStringTarget));
     wording.add(StringLiteral(", "));
   }
   if (allVariablesList.length != 0) {
@@ -392,8 +368,7 @@
 }
 
 void treatCopyWithCallSites(Component component, CoreTypes coreTypes,
-    TypeEnvironment typeEnvironment, ClassHierarchy hierarchy,
-    {required bool useNewMethodInvocationEncoding}) {
+    TypeEnvironment typeEnvironment, ClassHierarchy hierarchy) {
   ValueClassCopyWithScanner valueCopyWithScanner =
       new ValueClassCopyWithScanner();
   AllMemberScanner copyWithScanner = AllMemberScanner(valueCopyWithScanner);
@@ -415,8 +390,7 @@
           Class valueClass = valueClassType.classNode;
           if (isValueClass(valueClass)) {
             treatCopyWithCallSite(
-                valueClass, copyWithCall, coreTypes, hierarchy,
-                useNewMethodInvocationEncoding: useNewMethodInvocationEncoding);
+                valueClass, copyWithCall, coreTypes, hierarchy);
           }
         }
       }
@@ -428,8 +402,7 @@
     Class valueClass,
     InstanceInvocationExpression copyWithCall,
     CoreTypes coreTypes,
-    ClassHierarchy hierarchy,
-    {required bool useNewMethodInvocationEncoding}) {
+    ClassHierarchy hierarchy) {
   Map<String, Expression> preTransformationArguments = new Map();
   for (NamedExpression argument in copyWithCall.arguments.named) {
     preTransformationArguments[argument.name] = argument.value;
@@ -452,18 +425,15 @@
           argument.name!, preTransformationArguments[argument.name]!)
         ..parent = postTransformationArguments);
     } else {
-      postTransformationArguments.named.add(NamedExpression(
-          argument.name!,
-          _createGet(VariableGet(letVariable), Name(argument.name!),
-              useNewMethodInvocationEncoding: useNewMethodInvocationEncoding))
+      postTransformationArguments.named.add(NamedExpression(argument.name!,
+          _createGet(VariableGet(letVariable), Name(argument.name!)))
         ..parent = postTransformationArguments);
     }
   }
   copyWithCall.replaceWith(Let(
       letVariable,
       _createInvocation(VariableGet(letVariable), Name("copyWith"),
-          postTransformationArguments,
-          useNewMethodInvocationEncoding: useNewMethodInvocationEncoding)));
+          postTransformationArguments)));
 }
 
 bool isValueClass(Class node) {
@@ -483,47 +453,33 @@
 // access kind on InstanceInvocation.
 Expression _createInvocation(
     Expression receiver, Name name, Arguments arguments,
-    {Procedure? interfaceTarget,
-    required bool useNewMethodInvocationEncoding}) {
-  if (useNewMethodInvocationEncoding) {
-    if (interfaceTarget != null) {
-      return InstanceInvocation(
-          InstanceAccessKind.Instance, receiver, name, arguments,
-          interfaceTarget: interfaceTarget,
-          functionType: interfaceTarget.getterType as FunctionType);
-    } else {
-      return DynamicInvocation(
-          DynamicAccessKind.Dynamic, receiver, name, arguments);
-    }
+    {Procedure? interfaceTarget}) {
+  if (interfaceTarget != null) {
+    return InstanceInvocation(
+        InstanceAccessKind.Instance, receiver, name, arguments,
+        interfaceTarget: interfaceTarget,
+        functionType: interfaceTarget.getterType as FunctionType);
   } else {
-    return MethodInvocation(receiver, name, arguments, interfaceTarget);
+    return DynamicInvocation(
+        DynamicAccessKind.Dynamic, receiver, name, arguments);
   }
 }
 
 Expression _createEquals(Expression left, Expression right,
-    {required Procedure interfaceTarget,
-    required bool useNewMethodInvocationEncoding}) {
-  if (useNewMethodInvocationEncoding) {
-    return EqualsCall(left, right,
-        interfaceTarget: interfaceTarget,
-        functionType: interfaceTarget.getterType as FunctionType);
-  } else {
-    return MethodInvocation(left, Name('=='), Arguments([right]));
-  }
+    {required Procedure interfaceTarget}) {
+  return EqualsCall(left, right,
+      interfaceTarget: interfaceTarget,
+      functionType: interfaceTarget.getterType as FunctionType);
 }
 
 // TODO(johnniwinther): Ensure correct result type on InstanceGet.
 Expression _createGet(Expression receiver, Name name,
-    {Member? interfaceTarget, required bool useNewMethodInvocationEncoding}) {
-  if (useNewMethodInvocationEncoding) {
-    if (interfaceTarget != null) {
-      return InstanceGet(InstanceAccessKind.Instance, receiver, name,
-          interfaceTarget: interfaceTarget,
-          resultType: interfaceTarget.getterType);
-    } else {
-      return DynamicGet(DynamicAccessKind.Dynamic, receiver, name);
-    }
+    {Member? interfaceTarget}) {
+  if (interfaceTarget != null) {
+    return InstanceGet(InstanceAccessKind.Instance, receiver, name,
+        interfaceTarget: interfaceTarget,
+        resultType: interfaceTarget.getterType);
   } else {
-    return PropertyGet(receiver, name, interfaceTarget);
+    return DynamicGet(DynamicAccessKind.Dynamic, receiver, name);
   }
 }
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 68d7596..3d6cf83 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -637,61 +637,6 @@
   }
 
   @override
-  DartType visitMethodInvocation(MethodInvocation node) {
-    Member? target = node.interfaceTarget;
-    if (target == null) {
-      DartType receiver = visitExpression(node.receiver);
-      if (node.name.text == '==') {
-        visitExpression(node.arguments.positional.single);
-        return environment.coreTypes.boolLegacyRawType;
-      }
-      if (node.name.text == 'call' && receiver is FunctionType) {
-        return handleFunctionCall(node, receiver, node.arguments);
-      }
-      checkUnresolvedInvocation(receiver, node);
-      return handleDynamicCall(receiver, node.arguments);
-    } else if (target is Procedure &&
-        environment.isSpecialCasedBinaryOperator(target)) {
-      assert(node.arguments.positional.length == 1);
-      DartType receiver = visitExpression(node.receiver);
-      DartType argument = visitExpression(node.arguments.positional[0]);
-      return environment.getTypeOfSpecialCasedBinaryOperator(
-          receiver, argument);
-    } else {
-      return handleCall(node.arguments, target.getterType,
-          receiver: getReceiverType(node, node.receiver, target));
-    }
-  }
-
-  @override
-  DartType visitPropertyGet(PropertyGet node) {
-    Member? target = node.interfaceTarget;
-    if (target == null) {
-      final DartType receiver = visitExpression(node.receiver);
-      checkUnresolvedInvocation(receiver, node);
-      return const DynamicType();
-    } else {
-      Substitution receiver = getReceiverType(node, node.receiver, target);
-      return receiver.substituteType(target.getterType);
-    }
-  }
-
-  @override
-  DartType visitPropertySet(PropertySet node) {
-    Member? target = node.interfaceTarget;
-    DartType value = visitExpression(node.value);
-    if (target != null) {
-      Substitution receiver = getReceiverType(node, node.receiver, target);
-      checkAssignable(node.value, value,
-          receiver.substituteType(target.setterType, contravariant: true));
-    } else {
-      final DartType receiver = visitExpression(node.receiver);
-      checkUnresolvedInvocation(receiver, node);
-    }
-    return value;
-  }
-
-  @override
   DartType visitNot(Not node) {
     visitExpression(node.operand);
     return environment.coreTypes.boolLegacyRawType;
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 4a3134f..d7de1d7 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -23,8 +23,6 @@
   R visitInstanceGet(InstanceGet node) => defaultExpression(node);
   R visitInstanceSet(InstanceSet node) => defaultExpression(node);
   R visitInstanceTearOff(InstanceTearOff node) => defaultExpression(node);
-  R visitPropertyGet(PropertyGet node) => defaultExpression(node);
-  R visitPropertySet(PropertySet node) => defaultExpression(node);
   R visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node);
   R visitSuperPropertySet(SuperPropertySet node) => defaultExpression(node);
   R visitStaticGet(StaticGet node) => defaultExpression(node);
@@ -39,7 +37,6 @@
       defaultExpression(node);
   R visitEqualsNull(EqualsNull node) => defaultExpression(node);
   R visitEqualsCall(EqualsCall node) => defaultExpression(node);
-  R visitMethodInvocation(MethodInvocation node) => defaultExpression(node);
   R visitSuperMethodInvocation(SuperMethodInvocation node) =>
       defaultExpression(node);
   R visitStaticInvocation(StaticInvocation node) => defaultExpression(node);
@@ -200,8 +197,6 @@
   R visitInstanceGet(InstanceGet node) => defaultExpression(node);
   R visitInstanceSet(InstanceSet node) => defaultExpression(node);
   R visitInstanceTearOff(InstanceTearOff node) => defaultExpression(node);
-  R visitPropertyGet(PropertyGet node) => defaultExpression(node);
-  R visitPropertySet(PropertySet node) => defaultExpression(node);
   R visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node);
   R visitSuperPropertySet(SuperPropertySet node) => defaultExpression(node);
   R visitStaticGet(StaticGet node) => defaultExpression(node);
@@ -216,7 +211,6 @@
       defaultExpression(node);
   R visitEqualsNull(EqualsNull node) => defaultExpression(node);
   R visitEqualsCall(EqualsCall node) => defaultExpression(node);
-  R visitMethodInvocation(MethodInvocation node) => defaultExpression(node);
   R visitSuperMethodInvocation(SuperMethodInvocation node) =>
       defaultExpression(node);
   R visitStaticInvocation(StaticInvocation node) => defaultExpression(node);
@@ -356,8 +350,6 @@
   R visitInstanceSet(InstanceSet node, A arg) => defaultExpression(node, arg);
   R visitInstanceTearOff(InstanceTearOff node, A arg) =>
       defaultExpression(node, arg);
-  R visitPropertyGet(PropertyGet node, A arg) => defaultExpression(node, arg);
-  R visitPropertySet(PropertySet node, A arg) => defaultExpression(node, arg);
   R visitSuperPropertyGet(SuperPropertyGet node, A arg) =>
       defaultExpression(node, arg);
   R visitSuperPropertySet(SuperPropertySet node, A arg) =>
@@ -378,8 +370,6 @@
       defaultExpression(node, arg);
   R visitEqualsNull(EqualsNull node, A arg) => defaultExpression(node, arg);
   R visitEqualsCall(EqualsCall node, A arg) => defaultExpression(node, arg);
-  R visitMethodInvocation(MethodInvocation node, A arg) =>
-      defaultExpression(node, arg);
   R visitSuperMethodInvocation(SuperMethodInvocation node, A arg) =>
       defaultExpression(node, arg);
   R visitStaticInvocation(StaticInvocation node, A arg) =>
@@ -1524,8 +1514,6 @@
   R visitInstanceSet(InstanceSet node, T arg) => defaultExpression(node, arg);
   R visitInstanceTearOff(InstanceTearOff node, T arg) =>
       defaultExpression(node, arg);
-  R visitPropertyGet(PropertyGet node, T arg) => defaultExpression(node, arg);
-  R visitPropertySet(PropertySet node, T arg) => defaultExpression(node, arg);
   R visitSuperPropertyGet(SuperPropertyGet node, T arg) =>
       defaultExpression(node, arg);
   R visitSuperPropertySet(SuperPropertySet node, T arg) =>
@@ -1546,8 +1534,6 @@
       defaultExpression(node, arg);
   R visitEqualsNull(EqualsNull node, T arg) => defaultExpression(node, arg);
   R visitEqualsCall(EqualsCall node, T arg) => defaultExpression(node, arg);
-  R visitMethodInvocation(MethodInvocation node, T arg) =>
-      defaultExpression(node, arg);
   R visitSuperMethodInvocation(SuperMethodInvocation node, T arg) =>
       defaultExpression(node, arg);
   R visitStaticInvocation(StaticInvocation node, T arg) =>
diff --git a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
index fbdcefa..4261086 100644
--- a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
+++ b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
@@ -80,8 +80,8 @@
               type: const DynamicType(), initializer: new IntLiteral(42));
           VariableDeclaration innerLetVar = new VariableDeclaration('x',
               type: const NullType(), initializer: new NullLiteral());
-          return new ExpressionStatement(new Let(outerLetVar,
-              new Let(innerLetVar, new VariableGet(outerLetVar))));
+          return new ExpressionStatement(new Let(
+              outerLetVar, new Let(innerLetVar, new VariableGet(outerLetVar))));
         }(),
         expectation: ''
             '(expr (let "x^0" () (dynamic) (int 42) ()'
@@ -95,8 +95,8 @@
               type: const DynamicType(), initializer: new IntLiteral(42));
           VariableDeclaration innerLetVar = new VariableDeclaration('x',
               type: const NullType(), initializer: new NullLiteral());
-          return new ExpressionStatement(new Let(outerLetVar,
-              new Let(innerLetVar, new VariableGet(innerLetVar))));
+          return new ExpressionStatement(new Let(
+              outerLetVar, new Let(innerLetVar, new VariableGet(innerLetVar))));
         }(),
         expectation: ''
             '(expr (let "x^0" () (dynamic) (int 42) ()'
@@ -246,10 +246,14 @@
           new VariableDeclaration('x', type: const DynamicType());
       return new TestCase<Statement>(
           name: '/* suppose A {dynamic field;} A x; */ x.{A::field};',
-          node: new ExpressionStatement(new PropertyGet.byReference(
-              new VariableGet(x), field.name, field.getterReference)),
+          node: new ExpressionStatement(new InstanceGet.byReference(
+              InstanceAccessKind.Instance, new VariableGet(x), field.name,
+              interfaceTargetReference: field.getterReference,
+              resultType: field.getterType)),
           expectation: ''
-              '(expr (get-prop (get-var "x^0" _) (public "field")))',
+              '(expr (get-instance (instance) (get-var "x^0" _) '
+              '(public "field") "package:foo/bar.dart::A::@getters::field" '
+              '(dynamic)))',
           makeSerializationState: () =>
               new SerializationState(new SerializationEnvironment(null)
                 ..addBinder(x, nameClue: 'x')
@@ -274,10 +278,14 @@
           new VariableDeclaration('x', type: const DynamicType());
       return new TestCase<Statement>(
           name: '/* suppose A {dynamic field;} A x; */ x.{A::field};',
-          node: new ExpressionStatement(new PropertyGet.byReference(
-              new VariableGet(x), field.name, field.getterReference)),
+          node: new ExpressionStatement(new InstanceGet.byReference(
+              InstanceAccessKind.Instance, new VariableGet(x), field.name,
+              interfaceTargetReference: field.getterReference,
+              resultType: field.getterType)),
           expectation: ''
-              '(expr (get-prop (get-var "x^0" _) (public "field")))',
+              '(expr (get-instance (instance) (get-var "x^0" _) '
+              '(public "field") "package:foo/bar.dart::A::@getters::field" '
+              '(dynamic)))',
           makeSerializationState: () =>
               new SerializationState(new SerializationEnvironment(null)
                 ..addBinder(x, nameClue: 'x')
@@ -302,13 +310,16 @@
           new VariableDeclaration('x', type: const DynamicType());
       return new TestCase<Statement>(
           name: '/* suppose A {dynamic field;} A x; */ x.{A::field} = 42;',
-          node: new ExpressionStatement(PropertySet.byReference(
+          node: new ExpressionStatement(InstanceSet.byReference(
+              InstanceAccessKind.Instance,
               new VariableGet(x),
               field.name,
               new IntLiteral(42),
-              field.setterReference)),
+              interfaceTargetReference: field.setterReference!)),
           expectation: ''
-              '(expr (set-prop (get-var "x^0" _) (public "field") (int 42)))',
+              '(expr (set-instance (instance) (get-var "x^0" _) '
+              '(public "field") (int 42) '
+              '"package:foo/bar.dart::A::@setters::field"))',
           makeSerializationState: () =>
               new SerializationState(new SerializationEnvironment(null)
                 ..addBinder(x, nameClue: 'x')
@@ -335,14 +346,18 @@
           new VariableDeclaration('x', type: const DynamicType());
       return new TestCase<Statement>(
           name: '/* suppose A {foo() {...}} A x; */ x.{A::foo}();',
-          node: new ExpressionStatement(new MethodInvocation.byReference(
+          node: new ExpressionStatement(new InstanceInvocation.byReference(
+              InstanceAccessKind.Instance,
               new VariableGet(x),
               method.name,
               new Arguments([]),
-              method.reference)),
+              interfaceTargetReference: method.reference,
+              functionType: method.getterType as FunctionType)),
           expectation: ''
-              '(expr (invoke-method (get-var "x^0" _) (public "foo")'
-              ' () () ()))',
+              '(expr (invoke-instance (instance) (get-var "x^0" _) '
+              '(public "foo") () () () '
+              '"package:foo/bar.dart::A::@methods::foo" '
+              '(-> () () () () () () (dynamic))))',
           makeSerializationState: () =>
               new SerializationState(new SerializationEnvironment(null)
                 ..addBinder(x, nameClue: 'x')
diff --git a/pkg/kernel/test/text_serializer_test.dart b/pkg/kernel/test/text_serializer_test.dart
index ff8f0506..4fd8305 100644
--- a/pkg/kernel/test/text_serializer_test.dart
+++ b/pkg/kernel/test/text_serializer_test.dart
@@ -45,11 +45,7 @@
   final List<String> failures = [];
 
   void run() {
-    test('(get-prop (int 0) (public "hashCode"))');
     test('(get-super (public "hashCode"))');
-    test('(invoke-method (int 0) (public "foo") () ((int 1) (int 2)) ())');
-    test('(invoke-method (int 0) (public "foo") ((dynamic) (void)) '
-        '((int 1) (int 2)) ("others" (list (dynamic) ((int 3) (int 4)))))');
     test('(let "x^0" () (dynamic) (int 0) () (null))');
     test('(let "x^0" () (dynamic) _ () (null))');
     test('(let "x^0" ((const)) (dynamic) (int 0) () (null))');
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 3153b2e..97919d4 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -244,7 +244,9 @@
     'Dangling field get',
     (TestHarness test) {
       Field orphan = new Field.mutable(new Name('foo'), fileUri: dummyUri);
-      test.addNode(new PropertyGet(new NullLiteral(), orphan.name, orphan));
+      test.addNode(new InstanceGet(
+          InstanceAccessKind.Instance, new NullLiteral(), orphan.name,
+          interfaceTarget: orphan, resultType: orphan.getterType));
       return orphan;
     },
     (Node? node) => "Dangling reference to '$node', parent is: 'null'.",
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index ec6e1b1..01def63 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -64,9 +64,6 @@
       !flags.forceNoExplicitGetterCallsForTesting;
 
   @override
-  bool get supportsNewMethodInvocationEncoding => true;
-
-  @override
   int get enabledConstructorTearOffLowerings =>
       flags.forceConstructorTearOffLoweringForTesting;
 
diff --git a/pkg/vm/lib/transformations/call_site_annotator.dart b/pkg/vm/lib/transformations/call_site_annotator.dart
index 76803a9..2416787 100644
--- a/pkg/vm/lib/transformations/call_site_annotator.dart
+++ b/pkg/vm/lib/transformations/call_site_annotator.dart
@@ -60,18 +60,6 @@
   }
 
   @override
-  visitPropertyGet(PropertyGet node) =>
-      throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
-
-  @override
-  visitPropertySet(PropertySet node) =>
-      throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
-
-  @override
-  visitMethodInvocation(MethodInvocation node) =>
-      throw 'Unexpected node ${node.runtimeType}: $node at ${node.location}';
-
-  @override
   visitInstanceSet(InstanceSet node) {
     super.visitInstanceSet(node);
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 68734d6..9dd149c 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2855,7 +2855,7 @@
 
   // read flags.
   const uint8_t flags = is_dynamic ? 0 : ReadFlags();
-  const bool is_invariant = (flags & kMethodInvocationFlagInvariant) != 0;
+  const bool is_invariant = (flags & kInstanceInvocationFlagInvariant) != 0;
 
   const TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index c30f759..fb8c532 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,8 +20,8 @@
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
 
 // Both version numbers are inclusive.
-static const uint32_t kMinSupportedKernelFormatVersion = 68;
-static const uint32_t kMaxSupportedKernelFormatVersion = 68;
+static const uint32_t kMinSupportedKernelFormatVersion = 69;
+static const uint32_t kMaxSupportedKernelFormatVersion = 69;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -49,13 +49,10 @@
   V(InvalidExpression, 19)                                                     \
   V(VariableGet, 20)                                                           \
   V(VariableSet, 21)                                                           \
-  V(PropertyGet, 22)                                                           \
-  V(PropertySet, 23)                                                           \
   V(SuperPropertyGet, 24)                                                      \
   V(SuperPropertySet, 25)                                                      \
   V(StaticGet, 26)                                                             \
   V(StaticSet, 27)                                                             \
-  V(MethodInvocation, 28)                                                      \
   V(SuperMethodInvocation, 29)                                                 \
   V(StaticInvocation, 30)                                                      \
   V(ConstructorInvocation, 31)                                                 \
@@ -210,9 +207,9 @@
 };
 
 // Keep in sync with package:kernel/lib/ast.dart
-enum MethodInvocationFlags {
-  kMethodInvocationFlagInvariant = 1 << 0,
-  kMethodInvocationFlagBoundsSafe = 1 << 1,
+enum InstanceInvocationFlags {
+  kInstanceInvocationFlagInvariant = 1 << 0,
+  kInstanceInvocationFlagBoundsSafe = 1 << 1,
 };
 
 // Keep in sync with package:kernel/lib/ast.dart
diff --git a/tools/VERSION b/tools/VERSION
index 0e661f7..31673bd 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 361
+PRERELEASE 362
 PRERELEASE_PATCH 0
\ No newline at end of file