Version 2.18.0-197.0.dev

Merge commit 'b46a2d3039372506450ef7fe0f6d8241033392bb' into 'dev'
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
index 12d9fbb..1c684d6 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -16,6 +16,12 @@
 
 const jsonEncoder = JsonEncoder.withIndent('    ');
 
+typedef DocumentUri = String;
+typedef LSPAny = Object?;
+typedef LSPObject = Object;
+typedef TextDocumentEditEdits
+    = List<Either3<AnnotatedTextEdit, SnippetTextEdit, TextEdit>>;
+
 class AnalyzerStatusParams implements ToJsonable {
   static const jsonHandler = LspJsonHandler(
     AnalyzerStatusParams.canParse,
@@ -761,7 +767,7 @@
   @override
   final String jsonrpc;
   final Method method;
-  final Object? params;
+  final LSPAny params;
 
   @override
   Map<String, Object?> toJson() {
@@ -925,7 +931,7 @@
   @override
   final Method method;
   @override
-  final Object? params;
+  final LSPAny params;
 
   @override
   Map<String, Object?> toJson() {
@@ -1363,7 +1369,7 @@
   @override
   final Method method;
   @override
-  final Object? params;
+  final LSPAny params;
 
   @override
   Map<String, Object?> toJson() {
@@ -1548,7 +1554,7 @@
   final Either2<int, String>? id;
   @override
   final String jsonrpc;
-  final Object? result;
+  final LSPAny result;
 
   @override
   Map<String, Object?> toJson() {
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 8914bce..9e00504 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -16,6 +16,145 @@
 
 const jsonEncoder = JsonEncoder.withIndent('    ');
 
+/// An identifier to refer to a change annotation stored with a workspace edit.
+typedef ChangeAnnotationIdentifier = String;
+
+/// The declaration of a symbol representation as one or many locations.
+typedef Declaration = Either2<List<Location>, Location>;
+
+/// Information about where a symbol is declared.
+///
+/// Provides additional metadata over normal location declarations, including
+/// the range of the declaring symbol.
+///
+/// Servers should prefer returning `DeclarationLink` over `Declaration` if
+/// supported by the client.
+typedef DeclarationLink = LocationLink;
+
+/// The definition of a symbol represented as one or many locations. For most
+/// programming languages there is only one location at which a symbol is
+/// defined.
+///
+/// Servers should prefer returning `DefinitionLink` over `Definition` if
+/// supported by the client.
+typedef Definition = Either2<List<Location>, Location>;
+
+/// Information about where a symbol is defined.
+///
+/// Provides additional metadata over normal location definitions, including the
+/// range of the defining symbol
+typedef DefinitionLink = LocationLink;
+
+/// The result of a document diagnostic pull request. A report can either be a
+/// full report containing all diagnostics for the requested document or an
+/// unchanged report indicating that nothing has changed in terms of diagnostics
+/// in comparison to the last pull request.
+///
+/// @since 3.17.0
+typedef DocumentDiagnosticReport = Either2<RelatedFullDocumentDiagnosticReport,
+    RelatedUnchangedDocumentDiagnosticReport>;
+
+/// A document filter describes a top level text document or a notebook cell
+/// document.
+///
+/// @since 3.17.0 - proposed support for NotebookCellTextDocumentFilter.
+typedef DocumentFilter
+    = Either2<NotebookCellTextDocumentFilter, TextDocumentFilter>;
+
+/// A document selector is the combination of one or many document filters.
+///
+/// @sample `let sel:DocumentSelector = [{ language: 'typescript' }, { language:
+/// 'json', pattern: '**∕tsconfig.json' }]`;
+///
+/// The use of a string as a document filter is deprecated @since 3.16.0.
+typedef DocumentSelector = List<Either2<TextDocumentFilterWithScheme, String>>;
+
+/// The glob pattern. Either a string pattern or a relative pattern.
+///
+/// @since 3.17.0
+typedef GlobPattern = Either2<Pattern, RelativePattern>;
+
+/// Inline value information can be provided by different means:
+/// - directly as a text value (class InlineValueText).
+/// - as a name to use for a variable lookup (class InlineValueVariableLookup)
+/// - as an evaluatable expression (class InlineValueEvaluatableExpression) The
+/// InlineValue types combines all inline value types into one type.
+///
+/// @since 3.17.0
+typedef InlineValue = Either3<InlineValueEvaluatableExpression, InlineValueText,
+    InlineValueVariableLookup>;
+
+/// LSP arrays.
+/// @since 3.17.0
+typedef LSPArray = List<LSPAny>;
+
+/// A tagging type for string properties that are actually URIs
+///
+/// @since 3.16.0
+typedef LspUri = String;
+
+/// A notebook document filter denotes a notebook document by different
+/// properties. The properties will be match against the notebook's URI (same as
+/// with documents)
+///
+/// @since 3.17.0
+typedef NotebookDocumentFilter = Either3<NotebookDocumentFilter1,
+    NotebookDocumentFilter2, NotebookDocumentFilter3>;
+
+/// The glob pattern to watch relative to the base path. Glob patterns can have
+/// the following syntax:
+/// - `*` to match one or more characters in a path segment
+/// - `?` to match on one character in a path segment
+/// - `**` to match any number of path segments, including none
+/// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and
+/// JavaScript files)
+/// - `[]` to declare a range of characters to match in a path segment (e.g.,
+/// `example.[0-9]` to match on `example.0`, `example.1`, …)
+/// - `[!...]` to negate a range of characters to match in a path segment (e.g.,
+/// `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+///
+/// @since 3.17.0
+typedef Pattern = String;
+typedef PrepareRenameResult
+    = Either3<PlaceholderAndRange, PrepareRenameResult2, Range>;
+typedef ProgressToken = Either2<int, String>;
+
+/// An event describing a change to a text document. If only a text is provided
+/// it is considered to be the full content of the document.
+typedef TextDocumentContentChangeEvent
+    = Either2<TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2>;
+
+/// A document filter denotes a document by different properties like the
+/// language, the scheme of its resource, or a glob-pattern that is applied to
+/// the path.
+///
+/// Glob patterns can have the following syntax:
+/// - `*` to match one or more characters in a path segment
+/// - `?` to match on one character in a path segment
+/// - `**` to match any number of path segments, including none
+/// - `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}`
+/// matches all TypeScript and JavaScript files)
+/// - `[]` to declare a range of characters to match in a path segment (e.g.,
+/// `example.[0-9]` to match on `example.0`, `example.1`, …)
+/// - `[!...]` to negate a range of characters to match in a path segment (e.g.,
+/// `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+///
+/// @sample A language filter that applies to typescript files on disk: `{
+/// language: 'typescript', scheme: 'file' }`
+/// @sample A language filter that applies to all package.json paths: `{
+/// language: 'json', pattern: '**package.json' }`
+///
+/// @since 3.17.0
+typedef TextDocumentFilter = Either3<TextDocumentFilter1,
+    TextDocumentFilterWithScheme, TextDocumentFilter3>;
+
+/// A workspace diagnostic document report.
+///
+/// @since 3.17.0
+typedef WorkspaceDocumentDiagnosticReport = Either2<
+    WorkspaceFullDocumentDiagnosticReport,
+    WorkspaceUnchangedDocumentDiagnosticReport>;
+
 /// A special text edit with an additional change annotation.
 ///
 /// @since 3.16.0.
@@ -45,7 +184,7 @@
   }
 
   /// The actual identifier of the change annotation
-  final String annotationId;
+  final ChangeAnnotationIdentifier annotationId;
 
   /// The string to be inserted. For delete operations use an empty string.
   @override
@@ -547,11 +686,11 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -658,7 +797,7 @@
 
   /// A data entry field that is preserved between a call hierarchy prepare and
   /// incoming calls or outgoing calls requests.
-  final Object? data;
+  final LSPAny data;
 
   /// More detail for this item, e.g. the signature of a function.
   final String? detail;
@@ -681,7 +820,7 @@
   final List<SymbolTag>? tags;
 
   /// The resource identifier of this item.
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -938,11 +1077,11 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -1036,7 +1175,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -1386,7 +1525,7 @@
   }
 
   /// Experimental client capabilities.
-  final Object? experimental;
+  final LSPAny experimental;
 
   /// General client capabilities.
   ///
@@ -1552,7 +1691,7 @@
   /// `textDocument/codeAction` and a `codeAction/resolve` request.
   ///
   /// @since 3.16.0
-  final Object? data;
+  final LSPAny data;
 
   /// The diagnostics that this code action resolves.
   final List<Diagnostic>? diagnostics;
@@ -2430,7 +2569,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The range for which the command was invoked.
   final Range range;
@@ -2440,7 +2579,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -2686,7 +2825,7 @@
   }
 
   /// An URI to open with more information about the diagnostic error.
-  final String href;
+  final LspUri href;
 
   @override
   Map<String, Object?> toJson() {
@@ -2757,7 +2896,7 @@
 
   /// A data entry field that is preserved on a code lens item between a
   /// CodeLensRequest and a CodeLensResolveRequest
-  final Object? data;
+  final LSPAny data;
 
   /// The range in which this code lens is valid. Should only span a single
   /// line.
@@ -2972,14 +3111,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The document to request code lens for.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -3496,7 +3635,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The range where the color would be inserted. Serves as a context.
   final Range range;
@@ -3506,7 +3645,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -3604,7 +3743,7 @@
   }
 
   /// Arguments that the command handler should be invoked with.
-  final List<Object?>? arguments;
+  final List<LSPAny>? arguments;
 
   /// The identifier of the actual command handler.
   final String command;
@@ -3625,7 +3764,7 @@
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseListObject_(obj, reporter, 'arguments',
+      if (!_canParseListObjectNullable(obj, reporter, 'arguments',
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
@@ -3645,8 +3784,7 @@
   bool operator ==(Object other) {
     return other is Command &&
         other.runtimeType == Command &&
-        listEqual(
-            arguments, other.arguments, (Object? a, Object? b) => a == b) &&
+        listEqual(arguments, other.arguments, (LSPAny a, LSPAny b) => a == b) &&
         command == other.command &&
         title == other.title;
   }
@@ -5238,7 +5376,7 @@
   /// A default data value.
   ///
   /// @since 3.17.0
-  final Object? data;
+  final LSPAny data;
 
   /// A default edit range.
   ///
@@ -5585,7 +5723,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -5597,7 +5735,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -6051,7 +6189,7 @@
   ///
   /// @since 3.16.0
   @override
-  final String? annotationId;
+  final ChangeAnnotationIdentifier? annotationId;
 
   /// A create
   @override
@@ -6061,7 +6199,7 @@
   final CreateFileOptions? options;
 
   /// The resource to create.
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -6421,7 +6559,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -6433,7 +6571,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -6767,7 +6905,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -6779,7 +6917,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -6959,7 +7097,7 @@
   ///
   /// @since 3.16.0
   @override
-  final String? annotationId;
+  final ChangeAnnotationIdentifier? annotationId;
 
   /// A delete
   @override
@@ -6969,7 +7107,7 @@
   final DeleteFileOptions? options;
 
   /// The file to delete.
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -7232,7 +7370,7 @@
   /// `textDocument/codeAction` request.
   ///
   /// @since 3.16.0
-  final Object? data;
+  final LSPAny data;
 
   /// The diagnostic's message. It usually appears in the user interface
   final String message;
@@ -8036,7 +8174,7 @@
   }
 
   /// The actual changed settings
-  final Object? settings;
+  final LSPAny settings;
 
   @override
   Map<String, Object?> toJson() {
@@ -8199,9 +8337,7 @@
   /// - apply the `TextDocumentContentChangeEvent`s in a single notification in
   /// the order
   ///   you receive them.
-  final List<
-      Either2<TextDocumentContentChangeEvent1,
-          TextDocumentContentChangeEvent2>> contentChanges;
+  final List<TextDocumentContentChangeEvent> contentChanges;
 
   /// The document that did change. The version number points to the version
   /// after all provided content changes have been applied.
@@ -8238,12 +8374,8 @@
         listEqual(
             contentChanges,
             other.contentChanges,
-            (Either2<TextDocumentContentChangeEvent1,
-                            TextDocumentContentChangeEvent2>
-                        a,
-                    Either2<TextDocumentContentChangeEvent1,
-                            TextDocumentContentChangeEvent2>
-                        b) =>
+            (TextDocumentContentChangeEvent a,
+                    TextDocumentContentChangeEvent b) =>
                 a == b) &&
         textDocument == other.textDocument;
   }
@@ -9034,14 +9166,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The text document.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -9242,7 +9374,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The result id of a previous response if provided.
   final String? previousResultId;
@@ -9252,7 +9384,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -9349,7 +9481,7 @@
   }
 
   final Map<
-      String,
+      DocumentUri,
       Either2<FullDocumentDiagnosticReport,
           UnchangedDocumentDiagnosticReport>> relatedDocuments;
 
@@ -9546,7 +9678,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -9944,7 +10076,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -9956,7 +10088,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -10134,7 +10266,7 @@
 
   /// A data entry field that is preserved on a document link between a
   /// DocumentLinkRequest and a DocumentLinkResolveRequest.
-  final Object? data;
+  final LSPAny data;
 
   /// The range this link applies to.
   final Range range;
@@ -10390,14 +10522,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The document to provide document links for.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -11051,7 +11183,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -11743,14 +11875,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The text document.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -12146,14 +12278,14 @@
   }
 
   /// Arguments that the command should be invoked with.
-  final List<Object?>? arguments;
+  final List<LSPAny>? arguments;
 
   /// The identifier of the actual command handler.
   final String command;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -12170,7 +12302,7 @@
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      if (!_canParseListObject_(obj, reporter, 'arguments',
+      if (!_canParseListObjectNullable(obj, reporter, 'arguments',
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
@@ -12190,8 +12322,7 @@
   bool operator ==(Object other) {
     return other is ExecuteCommandParams &&
         other.runtimeType == ExecuteCommandParams &&
-        listEqual(
-            arguments, other.arguments, (Object? a, Object? b) => a == b) &&
+        listEqual(arguments, other.arguments, (LSPAny a, LSPAny b) => a == b) &&
         command == other.command &&
         workDoneToken == other.workDoneToken;
   }
@@ -12565,7 +12696,7 @@
   final FileChangeType type;
 
   /// The file's uri.
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -13345,7 +13476,7 @@
   /// detail.
   ///
   /// @since 3.17.0 support for relative patterns.
-  final Either2<String, RelativePattern> globPattern;
+  final GlobPattern globPattern;
 
   /// The kind of events of interest. If omitted it defaults to WatchKind.Create
   /// | WatchKind.Change | WatchKind.Delete which is 7.
@@ -13919,14 +14050,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The text document.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -14765,7 +14896,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -15069,7 +15200,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -15081,7 +15212,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -15315,7 +15446,7 @@
   final InitializeParamsClientInfo? clientInfo;
 
   /// User provided initialization options.
-  final Object? initializationOptions;
+  final LSPAny initializationOptions;
 
   /// The locale the client is currently showing the user interface in. This
   /// must not necessarily be the locale of the operating system.
@@ -15341,14 +15472,14 @@
   /// `rootPath` and `rootUri` are set `rootUri` wins.
   ///
   /// @deprecated in favour of workspaceFolders.
-  final String? rootUri;
+  final DocumentUri? rootUri;
 
   /// The initial trace setting. If omitted trace is disabled ('off').
   final String? trace;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   /// The workspace folders configured in the client when the server starts.
   ///
@@ -15771,7 +15902,7 @@
 
   /// A data entry field that is preserved on an inlay hint between a
   /// `textDocument/inlayHint` and a `inlayHint/resolve` request.
-  final Object? data;
+  final LSPAny data;
 
   /// The kind of this hint. Can be omitted in which case the client should fall
   /// back to a reasonable default.
@@ -16304,7 +16435,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -16849,7 +16980,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -17558,7 +17689,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -17813,7 +17944,7 @@
   }
 
   final Range range;
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -17908,7 +18039,7 @@
   final Range targetSelectionRange;
 
   /// The target resource identifier of this link.
-  final String targetUri;
+  final DocumentUri targetUri;
 
   @override
   Map<String, Object?> toJson() {
@@ -19028,7 +19159,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -19040,7 +19171,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -19219,7 +19350,7 @@
   }
 
   /// The URI of the cell's text document content.
-  final String document;
+  final DocumentUri document;
 
   /// Additional execution summary information if supported by the client.
   final ExecutionSummary? executionSummary;
@@ -19230,7 +19361,7 @@
   /// Additional metadata stored with the cell.
   ///
   /// Note: should always be an object literal (e.g. LSPObject)
-  final Object? metadata;
+  final LSPObject? metadata;
 
   @override
   Map<String, Object?> toJson() {
@@ -19256,8 +19387,12 @@
           allowsUndefined: true, allowsNull: false)) {
         return false;
       }
-      return _canParseNotebookCellKind(obj, reporter, 'kind',
-          allowsUndefined: false, allowsNull: false);
+      if (!_canParseNotebookCellKind(obj, reporter, 'kind',
+          allowsUndefined: false, allowsNull: false)) {
+        return false;
+      }
+      return _canParseObject(obj, reporter, 'metadata',
+          allowsUndefined: true, allowsNull: false);
     } else {
       reporter.reportError('must be of type NotebookCell');
       return false;
@@ -19442,10 +19577,7 @@
   /// A filter that matches against the notebook containing the notebook cell.
   /// If a string value is provided it matches against the notebook type. '*'
   /// matches every notebook.
-  final Either2<
-      Either3<NotebookDocumentFilter1, NotebookDocumentFilter2,
-          NotebookDocumentFilter3>,
-      String> notebook;
+  final Either2<NotebookDocumentFilter, String> notebook;
 
   @override
   Map<String, Object?> toJson() {
@@ -19534,13 +19666,13 @@
   /// Additional metadata stored with the notebook document.
   ///
   /// Note: should always be an object literal (e.g. LSPObject)
-  final Object? metadata;
+  final LSPObject? metadata;
 
   /// The type of the notebook.
   final String notebookType;
 
   /// The notebook document's uri.
-  final String uri;
+  final LspUri uri;
 
   /// The version number of this document (it will increase after each change,
   /// including undo/redo).
@@ -19565,6 +19697,10 @@
           allowsUndefined: false, allowsNull: false)) {
         return false;
       }
+      if (!_canParseObject(obj, reporter, 'metadata',
+          allowsUndefined: true, allowsNull: false)) {
+        return false;
+      }
       if (!_canParseString(obj, reporter, 'notebookType',
           allowsUndefined: false, allowsNull: false)) {
         return false;
@@ -19639,7 +19775,7 @@
   /// The changed meta data if any.
   ///
   /// Note: should always be an object literal (e.g. LSPObject)
-  final Object? metadata;
+  final LSPObject? metadata;
 
   @override
   Map<String, Object?> toJson() {
@@ -19655,7 +19791,11 @@
 
   static bool canParse(Object? obj, LspJsonReporter reporter) {
     if (obj is Map<String, Object?>) {
-      return _canParseNotebookDocumentChangeEventCells(obj, reporter, 'cells',
+      if (!_canParseNotebookDocumentChangeEventCells(obj, reporter, 'cells',
+          allowsUndefined: true, allowsNull: false)) {
+        return false;
+      }
+      return _canParseObject(obj, reporter, 'metadata',
           allowsUndefined: true, allowsNull: false);
     } else {
       reporter.reportError('must be of type NotebookDocumentChangeEvent');
@@ -19908,9 +20048,7 @@
     );
   }
 
-  final List<
-      Either2<TextDocumentContentChangeEvent1,
-          TextDocumentContentChangeEvent2>> changes;
+  final List<TextDocumentContentChangeEvent> changes;
   final VersionedTextDocumentIdentifier document;
 
   @override
@@ -19944,12 +20082,8 @@
         listEqual(
             changes,
             other.changes,
-            (Either2<TextDocumentContentChangeEvent1,
-                            TextDocumentContentChangeEvent2>
-                        a,
-                    Either2<TextDocumentContentChangeEvent1,
-                            TextDocumentContentChangeEvent2>
-                        b) =>
+            (TextDocumentContentChangeEvent a,
+                    TextDocumentContentChangeEvent b) =>
                 a == b) &&
         document == other.document;
   }
@@ -20300,7 +20434,7 @@
   }
 
   /// The notebook document's uri.
-  final String uri;
+  final LspUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -20545,10 +20679,7 @@
 
   /// The notebook to be synced If a string value is provided it matches against
   /// the notebook type. '*' matches every notebook.
-  final Either2<
-      Either3<NotebookDocumentFilter1, NotebookDocumentFilter2,
-          NotebookDocumentFilter3>,
-      String> notebook;
+  final Either2<NotebookDocumentFilter, String> notebook;
 
   @override
   Map<String, Object?> toJson() {
@@ -20634,10 +20765,7 @@
 
   /// The notebook to be synced If a string value is provided it matches against
   /// the notebook type. '*' matches every notebook.
-  final Either2<
-      Either3<NotebookDocumentFilter1, NotebookDocumentFilter2,
-          NotebookDocumentFilter3>,
-      String>? notebook;
+  final Either2<NotebookDocumentFilter, String>? notebook;
 
   @override
   Map<String, Object?> toJson() {
@@ -20936,7 +21064,7 @@
 
   /// The text document's uri.
   @override
-  final String uri;
+  final DocumentUri uri;
 
   /// The version number of this document. If a versioned text document
   /// identifier is sent from the server to the client and the file is not open
@@ -21169,7 +21297,7 @@
 
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -21449,7 +21577,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -21601,7 +21729,7 @@
   }
 
   /// The URI for which the client knowns a result id.
-  final String uri;
+  final DocumentUri uri;
 
   /// The value of the previous result id.
   final String value;
@@ -21668,10 +21796,10 @@
   }
 
   /// The progress token provided by the client or server.
-  final Either2<int, String> token;
+  final ProgressToken token;
 
   /// The progress data.
-  final Object? value;
+  final LSPAny value;
 
   @override
   Map<String, Object?> toJson() {
@@ -21935,7 +22063,7 @@
   final List<Diagnostic> diagnostics;
 
   /// The URI for which diagnostic information is reported.
-  final String uri;
+  final DocumentUri uri;
 
   /// Optional the version number of the document the diagnostics are published
   /// for.
@@ -22285,7 +22413,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -22297,7 +22425,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -22479,7 +22607,7 @@
   final String method;
 
   /// Options necessary for the registration.
-  final Object? registerOptions;
+  final LSPAny registerOptions;
 
   @override
   Map<String, Object?> toJson() {
@@ -22714,7 +22842,7 @@
   ///
   /// @since 3.17.0
   final Map<
-      String,
+      DocumentUri,
       Either2<FullDocumentDiagnosticReport,
           UnchangedDocumentDiagnosticReport>>? relatedDocuments;
 
@@ -22843,7 +22971,7 @@
   ///
   /// @since 3.17.0
   final Map<
-      String,
+      DocumentUri,
       Either2<FullDocumentDiagnosticReport,
           UnchangedDocumentDiagnosticReport>>? relatedDocuments;
 
@@ -22940,10 +23068,10 @@
 
   /// A workspace folder or a base URI to which this pattern will be matched
   /// against relatively.
-  final Either2<String, WorkspaceFolder> baseUri;
+  final Either2<LspUri, WorkspaceFolder> baseUri;
 
   /// The actual glob pattern;
-  final String pattern;
+  final Pattern pattern;
 
   @override
   Map<String, Object?> toJson() {
@@ -23151,17 +23279,17 @@
   ///
   /// @since 3.16.0
   @override
-  final String? annotationId;
+  final ChangeAnnotationIdentifier? annotationId;
 
   /// A rename
   @override
   final String kind;
 
   /// The new location.
-  final String newUri;
+  final DocumentUri newUri;
 
   /// The old (existing) location.
-  final String oldUri;
+  final DocumentUri oldUri;
 
   /// Rename options.
   final RenameFileOptions? options;
@@ -23481,7 +23609,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -23672,7 +23800,7 @@
   /// An optional annotation identifier describing the operation.
   ///
   /// @since 3.16.0
-  final String? annotationId;
+  final ChangeAnnotationIdentifier? annotationId;
 
   /// The resource operation kind.
   final String kind;
@@ -24042,7 +24170,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The positions inside the text document.
   final List<Position> positions;
@@ -24052,7 +24180,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -24869,7 +24997,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The result id of a previous response. The result Id can either point to a
   /// full response or a delta response depending on what was received last.
@@ -24880,7 +25008,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -25385,14 +25513,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The text document.
   final TextDocumentIdentifier textDocument;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -25535,7 +25663,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The range the semantic tokens are requested for.
   final Range range;
@@ -25545,7 +25673,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -26130,7 +26258,7 @@
   final ExecuteCommandOptions? executeCommandProvider;
 
   /// Experimental server capabilities.
-  final Object? experimental;
+  final LSPAny experimental;
 
   /// The server provides folding provider support.
   final Either3<bool, FoldingRangeOptions, FoldingRangeRegistrationOptions>?
@@ -26828,7 +26956,7 @@
   final bool? takeFocus;
 
   /// The document uri to show.
-  final String uri;
+  final LspUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -27795,7 +27923,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -29424,7 +29552,7 @@
   ///
   /// @since 3.16.0 - support for AnnotatedTextEdit. This is guarded using a
   /// client capability.
-  final List<Either3<AnnotatedTextEdit, SnippetTextEdit, TextEdit>> edits;
+  final TextDocumentEditEdits edits;
 
   /// The text document to change.
   final OptionalVersionedTextDocumentIdentifier textDocument;
@@ -29757,7 +29885,7 @@
   }
 
   /// The text document's uri.
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -29827,7 +29955,7 @@
   final String text;
 
   /// The text document's uri.
-  final String uri;
+  final DocumentUri uri;
 
   /// The version number of this document (it will increase after each change,
   /// including undo/redo).
@@ -30845,7 +30973,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The position inside the text document.
   @override
@@ -30857,7 +30985,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -31128,7 +31256,7 @@
   /// supertypes or subtypes requests. It could also be used to identify the
   /// type hierarchy in the server, helping improve the performance on resolving
   /// supertypes and subtypes.
-  final Object? data;
+  final LSPAny data;
 
   /// More detail for this item, e.g. the signature of a function.
   final String? detail;
@@ -31151,7 +31279,7 @@
   final List<SymbolTag>? tags;
 
   /// The resource identifier of this item.
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -31337,7 +31465,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -31529,11 +31657,11 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -31623,11 +31751,11 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -31954,7 +32082,7 @@
   }
 
   /// The notebook document's uri.
-  final String uri;
+  final LspUri uri;
 
   /// The version number of this notebook document.
   final int version;
@@ -32025,7 +32153,7 @@
 
   /// The text document's uri.
   @override
-  final String uri;
+  final DocumentUri uri;
 
   /// The version number of this document.
   final int version;
@@ -32425,7 +32553,7 @@
   }
 
   /// The token to be used to report progress.
-  final Either2<int, String> token;
+  final ProgressToken token;
 
   @override
   Map<String, Object?> toJson() {
@@ -32476,7 +32604,7 @@
   }
 
   /// The token to be used to report progress.
-  final Either2<int, String> token;
+  final ProgressToken token;
 
   @override
   Map<String, Object?> toJson() {
@@ -32857,7 +32985,7 @@
   }
 
   /// An optional token that a server can use to report work done progress.
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -33381,14 +33509,14 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// The currently known diagnostic reports with their previous result ids.
   final List<PreviousResultId> previousResultIds;
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -33476,9 +33604,7 @@
     );
   }
 
-  final List<
-      Either2<WorkspaceFullDocumentDiagnosticReport,
-          WorkspaceUnchangedDocumentDiagnosticReport>> items;
+  final List<WorkspaceDocumentDiagnosticReport> items;
 
   @override
   Map<String, Object?> toJson() {
@@ -33505,12 +33631,8 @@
         listEqual(
             items,
             other.items,
-            (Either2<WorkspaceFullDocumentDiagnosticReport,
-                            WorkspaceUnchangedDocumentDiagnosticReport>
-                        a,
-                    Either2<WorkspaceFullDocumentDiagnosticReport,
-                            WorkspaceUnchangedDocumentDiagnosticReport>
-                        b) =>
+            (WorkspaceDocumentDiagnosticReport a,
+                    WorkspaceDocumentDiagnosticReport b) =>
                 a == b);
   }
 
@@ -33546,9 +33668,7 @@
     );
   }
 
-  final List<
-      Either2<WorkspaceFullDocumentDiagnosticReport,
-          WorkspaceUnchangedDocumentDiagnosticReport>> items;
+  final List<WorkspaceDocumentDiagnosticReport> items;
 
   @override
   Map<String, Object?> toJson() {
@@ -33576,12 +33696,8 @@
         listEqual(
             items,
             other.items,
-            (Either2<WorkspaceFullDocumentDiagnosticReport,
-                            WorkspaceUnchangedDocumentDiagnosticReport>
-                        a,
-                    Either2<WorkspaceFullDocumentDiagnosticReport,
-                            WorkspaceUnchangedDocumentDiagnosticReport>
-                        b) =>
+            (WorkspaceDocumentDiagnosticReport a,
+                    WorkspaceDocumentDiagnosticReport b) =>
                 a == b);
   }
 
@@ -33650,10 +33766,10 @@
   /// `workspace.changeAnnotationSupport`.
   ///
   /// @since 3.16.0
-  final Map<String, ChangeAnnotation>? changeAnnotations;
+  final Map<ChangeAnnotationIdentifier, ChangeAnnotation>? changeAnnotations;
 
   /// Holds changes to existing resources.
-  final Map<String, List<TextEdit>>? changes;
+  final Map<DocumentUri, List<TextEdit>>? changes;
 
   /// Depending on the client capability
   /// `workspace.workspaceEdit.resourceOperations` document changes are either
@@ -33968,7 +34084,7 @@
   final String name;
 
   /// The associated URI for this workspace folder.
-  final String uri;
+  final LspUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -34222,7 +34338,7 @@
   final String? resultId;
 
   /// The URI for which diagnostic information is reported.
-  final String uri;
+  final DocumentUri uri;
 
   /// The version number for which the diagnostics are reported. If the document
   /// is not marked as open `null` can be provided.
@@ -34345,7 +34461,7 @@
 
   /// A data entry field that is preserved on a workspace symbol between a
   /// workspace symbol request and a workspace symbol resolve request.
-  final Object? data;
+  final LSPAny data;
 
   /// The kind of this symbol.
   @override
@@ -34753,7 +34869,7 @@
     );
   }
 
-  final String uri;
+  final DocumentUri uri;
 
   @override
   Map<String, Object?> toJson() {
@@ -34897,7 +35013,7 @@
   /// An optional token that a server can use to report partial results (e.g.
   /// streaming) to the client.
   @override
-  final Either2<int, String>? partialResultToken;
+  final ProgressToken? partialResultToken;
 
   /// A query string to filter symbols by. Clients may send an empty string here
   /// to request all symbols.
@@ -34905,7 +35021,7 @@
 
   /// An optional token that a server can use to report work done progress.
   @override
-  final Either2<int, String>? workDoneToken;
+  final ProgressToken? workDoneToken;
 
   @override
   Map<String, Object?> toJson() {
@@ -35085,7 +35201,7 @@
   final String resultId;
 
   /// The URI for which diagnostic information is reported.
-  final String uri;
+  final DocumentUri uri;
 
   /// The version number for which the diagnostics are reported. If the document
   /// is not marked as open `null` can be provided.
@@ -39108,7 +39224,7 @@
   return true;
 }
 
-bool _canParseListObject_(
+bool _canParseListObjectNullable(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
   reporter.push(fieldName);
@@ -39125,7 +39241,7 @@
     }
     if ((!nullCheck || value != null) &&
         (value is! List<Object?> || value.any((item) => false))) {
-      reporter.reportError('must be of type List<Object?>');
+      reporter.reportError('must be of type List<LSPAny>');
       return false;
     }
   } finally {
@@ -39483,8 +39599,8 @@
             value.any((item) =>
                 !TextDocumentContentChangeEvent1.canParse(item, reporter) &&
                 !TextDocumentContentChangeEvent2.canParse(item, reporter)))) {
-      reporter.reportError(
-          'must be of type List<Either2<TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2>>');
+      reporter
+          .reportError('must be of type List<TextDocumentContentChangeEvent>');
       return false;
     }
   } finally {
@@ -39709,7 +39825,7 @@
                 !WorkspaceUnchangedDocumentDiagnosticReport.canParse(
                     item, reporter)))) {
       reporter.reportError(
-          'must be of type List<Either2<WorkspaceFullDocumentDiagnosticReport, WorkspaceUnchangedDocumentDiagnosticReport>>');
+          'must be of type List<WorkspaceDocumentDiagnosticReport>');
       return false;
     }
   } finally {
@@ -39847,7 +39963,8 @@
                 item is! String ||
                 value.values.any(
                     (item) => !ChangeAnnotation.canParse(item, reporter)))))) {
-      reporter.reportError('must be of type Map<String, ChangeAnnotation>');
+      reporter.reportError(
+          'must be of type Map<ChangeAnnotationIdentifier, ChangeAnnotation>');
       return false;
     }
   } finally {
@@ -39881,7 +39998,7 @@
                     !UnchangedDocumentDiagnosticReport.canParse(
                         item, reporter)))))) {
       reporter.reportError(
-          'must be of type Map<String, Either2<FullDocumentDiagnosticReport, UnchangedDocumentDiagnosticReport>>');
+          'must be of type Map<DocumentUri, Either2<FullDocumentDiagnosticReport, UnchangedDocumentDiagnosticReport>>');
       return false;
     }
   } finally {
@@ -39913,7 +40030,7 @@
                     item is! List<Object?> ||
                     item.any(
                         (item) => !TextEdit.canParse(item, reporter))))))) {
-      reporter.reportError('must be of type Map<String, List<TextEdit>>');
+      reporter.reportError('must be of type Map<DocumentUri, List<TextEdit>>');
       return false;
     }
   } finally {
@@ -40284,7 +40401,7 @@
             !NotebookDocumentFilter3.canParse(value, reporter) &&
             value is! String)) {
       reporter.reportError(
-          'must be of type Either2<Either3<NotebookDocumentFilter1, NotebookDocumentFilter2, NotebookDocumentFilter3>, String>');
+          'must be of type Either2<NotebookDocumentFilter, String>');
       return false;
     }
   } finally {
@@ -40401,6 +40518,31 @@
   return true;
 }
 
+bool _canParseObject(
+    Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
+    {required bool allowsUndefined, required bool allowsNull}) {
+  reporter.push(fieldName);
+  try {
+    if (!allowsUndefined && !map.containsKey(fieldName)) {
+      reporter.reportError('must not be undefined');
+      return false;
+    }
+    final value = map[fieldName];
+    final nullCheck = allowsNull || allowsUndefined;
+    if (!nullCheck && value == null) {
+      reporter.reportError('must not be null');
+      return false;
+    }
+    if ((!nullCheck || value != null) && value == null) {
+      reporter.reportError('must be of type Object');
+      return false;
+    }
+  } finally {
+    reporter.pop();
+  }
+  return true;
+}
+
 bool _canParseOptionalVersionedTextDocumentIdentifier(
     Map<String, Object?> map, LspJsonReporter reporter, String fieldName,
     {required bool allowsUndefined, required bool allowsNull}) {
@@ -41262,7 +41404,7 @@
     }
     if ((!nullCheck || value != null) &&
         (value is! String && !RelativePattern.canParse(value, reporter))) {
-      reporter.reportError('must be of type Either2<String, RelativePattern>');
+      reporter.reportError('must be of type Either2<Pattern, RelativePattern>');
       return false;
     }
   } finally {
@@ -41288,7 +41430,7 @@
     }
     if ((!nullCheck || value != null) &&
         (value is! String && !WorkspaceFolder.canParse(value, reporter))) {
-      reporter.reportError('must be of type Either2<String, WorkspaceFolder>');
+      reporter.reportError('must be of type Either2<LspUri, WorkspaceFolder>');
       return false;
     }
   } finally {
@@ -42477,10 +42619,7 @@
               : throw '$value was not one of (NotebookDocumentFilter1, NotebookDocumentFilter2, NotebookDocumentFilter3)';
 }
 
-Either2<
-        Either3<NotebookDocumentFilter1, NotebookDocumentFilter2,
-            NotebookDocumentFilter3>,
-        String>
+Either2<NotebookDocumentFilter, String>
     _eitherNotebookDocumentFilter1NotebookDocumentFilter2NotebookDocumentFilter3String(
         Object? value) {
   return NotebookDocumentFilter1.canParse(value, nullLspJsonReporter) ||
@@ -42491,7 +42630,7 @@
               value))
       : value is String
           ? Either2.t2(value)
-          : throw '$value was not one of (Either3<NotebookDocumentFilter1, NotebookDocumentFilter2, NotebookDocumentFilter3>, String)';
+          : throw '$value was not one of (NotebookDocumentFilter, String)';
 }
 
 Either2<NotebookDocumentSyncOptions, NotebookDocumentSyncRegistrationOptions>
@@ -42534,20 +42673,20 @@
           : throw '$value was not one of (SemanticTokensOptions, SemanticTokensRegistrationOptions)';
 }
 
-Either2<String, RelativePattern> _eitherStringRelativePattern(Object? value) {
+Either2<Pattern, RelativePattern> _eitherStringRelativePattern(Object? value) {
   return value is String
       ? Either2.t1(value)
       : RelativePattern.canParse(value, nullLspJsonReporter)
           ? Either2.t2(RelativePattern.fromJson(value as Map<String, Object?>))
-          : throw '$value was not one of (String, RelativePattern)';
+          : throw '$value was not one of (Pattern, RelativePattern)';
 }
 
-Either2<String, WorkspaceFolder> _eitherStringWorkspaceFolder(Object? value) {
+Either2<LspUri, WorkspaceFolder> _eitherStringWorkspaceFolder(Object? value) {
   return value is String
       ? Either2.t1(value)
       : WorkspaceFolder.canParse(value, nullLspJsonReporter)
           ? Either2.t2(WorkspaceFolder.fromJson(value as Map<String, Object?>))
-          : throw '$value was not one of (String, WorkspaceFolder)';
+          : throw '$value was not one of (LspUri, WorkspaceFolder)';
 }
 
 Either2<TextDocumentContentChangeEvent1, TextDocumentContentChangeEvent2>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 0440ae0..1e44d82 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -4,7 +4,7 @@
 
 import 'dart:math' as math;
 
-import 'package:analysis_server/lsp_protocol/protocol.dart';
+import 'package:analysis_server/lsp_protocol/protocol.dart' hide Declaration;
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/lsp/client_capabilities.dart';
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index b3053c1..518bf16 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -5,7 +5,7 @@
 import 'dart:io';
 import 'dart:math';
 
-import 'package:analysis_server/lsp_protocol/protocol.dart';
+import 'package:analysis_server/lsp_protocol/protocol.dart' hide Declaration;
 import 'package:analysis_server/lsp_protocol/protocol.dart' as lsp;
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/lsp/client_capabilities.dart';
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 2799810..b3f677f 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -1753,7 +1753,7 @@
   Future<ResponseMessage> sendDidChangeConfiguration() {
     final request = makeRequest(
       Method.workspace_didChangeConfiguration,
-      DidChangeConfigurationParams(),
+      DidChangeConfigurationParams(settings: {}),
     );
     return sendRequestToServer(request);
   }
diff --git a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
index 7384167..636f8c3 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
@@ -11,7 +11,6 @@
     test('handles basic types', () {
       expect(_simple('string').dartType, equals('String'));
       expect(_simple('boolean').dartType, equals('bool'));
-      expect(_simple('any').dartType, equals('Object?'));
       expect(_simple('object').dartType, equals('Object?'));
       expect(_simple('int').dartType, equals('int'));
       expect(_simple('num').dartType, equals('num'));
diff --git a/pkg/analysis_server/test/tool/lsp_spec/meta_model_test.dart b/pkg/analysis_server/test/tool/lsp_spec/meta_model_test.dart
index b9632ff..b854fbe 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/meta_model_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/meta_model_test.dart
@@ -4,11 +4,18 @@
 
 import 'package:test/test.dart';
 
+import '../../../tool/lsp_spec/codegen_dart.dart';
+import '../../../tool/lsp_spec/generate_all.dart';
 import '../../../tool/lsp_spec/meta_model.dart';
 import 'matchers.dart';
 
 void main() {
   group('meta model reader', () {
+    setUpAll(() {
+      // Ensure any custom types like LSPAny are registered so that they can
+      // be resolved.
+      recordTypes(getCustomClasses());
+    });
     test('reads an interface', () {
       final input = {
         "structures": [
@@ -445,7 +452,7 @@
       expect(union.types[1], isSimpleType('string'));
     });
 
-    test('reads an union including LSPObject into a single type', () {
+    test('reads an union including LSPAny into a single type', () {
       final input = {
         "structures": [
           {
@@ -457,7 +464,7 @@
                   "kind": "or",
                   "items": [
                     {"kind": "base", "name": "string"},
-                    {"kind": "base", "name": "LSPObject"},
+                    {"kind": "base", "name": "LSPAny"},
                   ]
                 },
               },
@@ -473,7 +480,7 @@
       final field = interface.members.first as Field;
       expect(field, const TypeMatcher<Field>());
       expect(field.name, equals('label'));
-      expect(field.type, isSimpleType('LSPObject'));
+      expect(field.type, isSimpleType('LSPAny'));
     });
 
     test('reads literal string values', () {
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 344a176..5c04744 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -43,7 +43,15 @@
   _canParseFunctions.clear();
   _unionFunctions.clear();
   final buffer = IndentableStringBuffer();
-  _getSortedUnique(types).forEach((t) => _writeType(buffer, t));
+  final sortedTypes = _getSortedUnique(types);
+  // Bump typedefs to the top.
+  final fileSortedTypes = [
+    ...sortedTypes.whereType<TypeAlias>(),
+    ...sortedTypes.where((type) => type is! TypeAlias),
+  ];
+  for (var type in fileSortedTypes) {
+    _writeType(buffer, type);
+  }
   for (var function in _canParseFunctions.values) {
     buffer.writeln(function);
   }
@@ -79,9 +87,16 @@
   _sortSubtypes();
 }
 
-TypeBase resolveTypeAlias(TypeBase type, {bool resolveEnumClasses = false}) {
+/// Resolves [type] to its base type if it is a reference to another type.
+///
+/// If [resolveEnums] is `true`, will resolve them to the type of their values.
+///
+/// If [onlyRenames] is true, references to [TypeAlias]es will only be resolved
+/// if they are renames.
+TypeBase resolveTypeAlias(TypeBase type,
+    {bool resolveEnums = false, bool onlyRenames = false}) {
   if (type is TypeReference) {
-    if (resolveEnumClasses) {
+    if (resolveEnums) {
       // Enums are no longer recorded with TypeAliases (as they were in the
       // Markdown/TS spec) so must be resolved explicitly to their base types.
       final enum_ = _namespaces[type.name];
@@ -89,19 +104,20 @@
         return enum_.typeOfValues;
       }
     }
-    // The LSP spec contains type aliases for `integer` and `uinteger` that map
-    // into the `number` type, with comments stating they must be integers. To
-    // preserve the improved typing, do _not_ resolve them to the `number`
-    // type.
-    if (type.name == 'integer' || type.name == 'uinteger') {
-      return type;
-    }
 
     final alias = _typeAliases[type.name];
-    // Only follow the type if we're not an enum, or we wanted to follow enums.
-    if (alias != null &&
-        (!_namespaces.containsKey(alias.name) || resolveEnumClasses)) {
-      return alias.baseType;
+    if (alias != null && (!onlyRenames || alias.isRename)) {
+      // Resolve aliases recursively.
+      var resolved = alias.baseType;
+      for (int i = 0; i < 10; i++) {
+        final newResolved = resolveTypeAlias(resolved,
+            resolveEnums: resolveEnums, onlyRenames: onlyRenames);
+        if (newResolved == resolved) {
+          return resolved;
+        }
+        resolved = newResolved;
+      }
+      throw 'Failed to resolve type after 10 iterations: ${alias.name}';
     }
   }
   return type;
@@ -215,7 +231,8 @@
 bool _isSpecType(TypeBase type) {
   type = resolveTypeAlias(type);
   return type is TypeReference &&
-      !isAnyType(type) &&
+      type != TypeReference.LspObject &&
+      type != TypeReference.LspAny &&
       (_interfaces.containsKey(type.name) ||
           (_namespaces.containsKey(type.name)));
 }
@@ -246,14 +263,17 @@
   if (type is TypeReference) {
     type = resolveTypeAlias(type);
   }
-  var dartType = type is UnionType
-      ? type.types.map(_memberNameForType).join()
-      : type is ArrayType
-          ? 'List${_memberNameForType(type.elementType)}'
-          : type is MapType
-              ? 'Map${_memberNameForType(type.indexType)}${_memberNameForType(type.valueType)}'
-              : type.dartType;
-  return capitalize(dartType.replaceAll('?', '_'));
+
+  var dartType = type is NullableType
+      ? '${type.dartType}?'
+      : type is UnionType
+          ? type.types.map(_memberNameForType).join()
+          : type is ArrayType
+              ? 'List${_memberNameForType(type.elementType)}'
+              : type is MapType
+                  ? 'Map${_memberNameForType(type.indexType)}${_memberNameForType(type.valueType)}'
+                  : type.dartType;
+  return capitalize(dartType.replaceAll('?', 'Nullable'));
 }
 
 String _rewriteCommentReference(String comment) {
@@ -308,8 +328,7 @@
 String _specJsonType(TypeBase type) {
   if (type is TypeReference && _namespaces.containsKey(type.name)) {
     final valueType = _namespaces[type.name]!.typeOfValues;
-    return resolveTypeAlias(valueType, resolveEnumClasses: true)
-        .dartTypeWithTypeArgs;
+    return valueType.dartTypeWithTypeArgs;
   }
   return 'Map<String, Object?>';
 }
@@ -346,8 +365,9 @@
   // In order to consider this valid for parsing, all fields that must not be
   // undefined must be present and also type check for the correct type.
   // Any fields that are optional but present, must still type check.
-  final fields =
-      _getAllFields(interface).whereNot((f) => isAnyType(f.type)).toList();
+  final fields = _getAllFields(interface)
+      .whereNot((f) => isNullableAnyType(f.type))
+      .toList();
   for (var i = 0; i < fields.length; i++) {
     final field = fields[i];
     var type = field.type;
@@ -463,7 +483,7 @@
       final isRequired = !isLiteral &&
           !field.allowsNull &&
           !field.allowsUndefined &&
-          !isAnyType(field.type);
+          !isNullableAnyType(field.type);
       final requiredKeyword = isRequired ? 'required' : '';
       final valueCode =
           isLiteral ? ' = ${(field.type as LiteralType).valueAsLiteral}' : '';
@@ -633,8 +653,8 @@
 void _writeField(
     IndentableStringBuffer buffer, Interface interface, Field field) {
   _writeDocCommentsAndAnnotations(buffer, field);
-  final needsNullable =
-      (field.allowsNull || field.allowsUndefined) && !isAnyType(field.type);
+  final needsNullable = (field.allowsNull || field.allowsUndefined) &&
+      !isNullableAnyType(field.type);
   if (_isOverride(interface, field)) {
     buffer.writeIndentedln('@override');
   }
@@ -654,7 +674,11 @@
 }) {
   type = resolveTypeAlias(type);
   final nullOperator = allowsNull ? '?' : '';
-  final cast = requiresCast && type.dartTypeWithTypeArgs != 'Object?'
+  final cast = requiresCast &&
+          // LSPAny
+          !isNullableAnyType(type) &&
+          // LSPObject marked as optional
+          !(isObjectType(type) && allowsNull)
       ? ' as ${type.dartTypeWithTypeArgs}$nullOperator'
       : '';
 
@@ -741,7 +765,7 @@
 
   for (var i = 0; i < union.types.length; i++) {
     final type = union.types[i];
-    final isAny = isAnyType(type);
+    final isAny = isNullableAnyType(type);
 
     // "any" matches all type checks, so only emit it if required.
     if (!isAny) {
@@ -1028,15 +1052,20 @@
   } else if (type is LspEnum) {
     _writeEnumClass(buffer, type);
   } else if (type is TypeAlias) {
-    // For now type aliases are not supported, so are collected at the start
-    // of the process in a map, and just replaced with the aliased type during
-    // generation.
-    // _writeTypeAlias(buffer, type);
+    _writeTypeAlias(buffer, type);
   } else {
     throw 'Unknown type';
   }
 }
 
+void _writeTypeAlias(IndentableStringBuffer buffer, TypeAlias alias) {
+  if (alias.isRename) return;
+  final baseType = alias.baseType;
+  final typeName = baseType.dartTypeWithTypeArgs;
+  _writeDocCommentsAndAnnotations(buffer, alias);
+  buffer.writeIndentedln('typedef ${alias.name} = $typeName;');
+}
+
 void _writeTypeCheckCondition(IndentableStringBuffer buffer,
     Interface? interface, String valueCode, TypeBase type, String reporter,
     {bool negation = false, bool parenForCollection = false}) {
@@ -1049,8 +1078,11 @@
   final and = negation ? '||' : '&&';
   final every = negation ? 'any' : 'every';
 
-  if (fullDartType == 'Object?') {
+  if (isNullableAnyType(type)) {
     buffer.write(negation ? 'false' : 'true');
+  } else if (isObjectType(type)) {
+    final notEqual = negation ? '==' : '!=';
+    buffer.write('$valueCode $notEqual null');
   } else if (_isSimpleType(type)) {
     buffer.write('$valueCode is$operator $fullDartType');
   } else if (type is LiteralType) {
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index d9aca9a..afe9147 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -142,11 +142,13 @@
   final customTypes = <LspEntity>[
     TypeAlias(
       name: 'LSPAny',
-      baseType: TypeReference.Any,
+      baseType: TypeReference.LspAny,
+      isRename: false,
     ),
     TypeAlias(
       name: 'LSPObject',
-      baseType: TypeReference.Any,
+      baseType: TypeReference.LspObject,
+      isRename: false,
     ),
     // The DocumentFilter more complex in v3.17's meta_model (to allow
     // TextDocumentFilters to be guaranteed to have at least one of language,
@@ -156,6 +158,7 @@
     TypeAlias(
       name: 'DocumentFilter',
       baseType: TypeReference('TextDocumentFilter2'),
+      isRename: true,
     ),
     // Similarly, the meta_model includes String as an option for
     // DocumentSelector which is deprecated and we never previously supported
@@ -165,6 +168,7 @@
     TypeAlias(
       name: 'DocumentSelector',
       baseType: ArrayType(TypeReference('TextDocumentFilterWithScheme')),
+      isRename: true,
     ),
     interface('Message', [
       field('jsonrpc', type: 'string'),
@@ -231,6 +235,7 @@
     TypeAlias(
       name: 'DocumentUri',
       baseType: TypeReference('string'),
+      isRename: false,
     ),
 
     interface('DartDiagnosticServer', [field('port', type: 'int')]),
@@ -335,6 +340,7 @@
           TypeReference('TextEdit'),
         ]),
       ),
+      isRename: false,
     )
   ];
   return customTypes;
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model.dart b/pkg/analysis_server/tool/lsp_spec/meta_model.dart
index 4c2d41e..20aadea 100644
--- a/pkg/analysis_server/tool/lsp_spec/meta_model.dart
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model.dart
@@ -9,19 +9,19 @@
 export 'meta_model_cleaner.dart';
 export 'meta_model_reader.dart';
 
-/// Whether this type allows any value (including null).
-bool isAnyType(TypeBase t) =>
-    t is TypeReference &&
-    (t.name == 'any' ||
-        t.name == 'LSPAny' ||
-        t.name == 'object' ||
-        t.name == 'LSPObject');
-
 bool isLiteralType(TypeBase t) => t is LiteralType;
 
-bool isNullType(TypeBase t) => t is TypeReference && t.name == 'null';
+/// Whether this type is the equivalent of 'Object?' and may also be omitted
+/// from JSON ("undefined").
+bool isNullableAnyType(TypeBase t) =>
+    resolveTypeAlias(t).dartTypeWithTypeArgs == 'Object?';
 
-bool isUndefinedType(TypeBase t) => t is TypeReference && t.name == 'undefined';
+bool isNullType(TypeBase t) =>
+    resolveTypeAlias(t).dartTypeWithTypeArgs == 'Null';
+
+/// Whether this type is the equivalent of (non-nullable) 'Object'.
+bool isObjectType(TypeBase t) =>
+    resolveTypeAlias(t).dartTypeWithTypeArgs == 'Object';
 
 class ArrayType extends TypeBase {
   final TypeBase elementType;
@@ -202,12 +202,35 @@
   });
 }
 
+class NullableType extends TypeBase {
+  final TypeBase baseType;
+
+  NullableType(this.baseType);
+
+  @override
+  String get dartType => baseType.dartType;
+
+  @override
+  String get dartTypeWithTypeArgs => '${super.dartTypeWithTypeArgs}?';
+
+  @override
+  String get typeArgsString => baseType.typeArgsString;
+}
+
 class TypeAlias extends LspEntity {
   final TypeBase baseType;
+
+  /// Whether this alias is just a simple rename and not a name for a more
+  /// complex type.
+  ///
+  /// Renames will be followed when generating code, but other aliases may be
+  /// created as `typedef`s.
+  final bool isRename;
   TypeAlias({
     required super.name,
     super.comment,
     required this.baseType,
+    required this.isRename,
   });
 }
 
@@ -215,6 +238,7 @@
 abstract class TypeBase {
   String get dartType;
   String get dartTypeWithTypeArgs => '$dartType$typeArgsString';
+
   String get typeArgsString;
 
   /// A unique identifier for this type. Used for folding types together
@@ -225,8 +249,13 @@
 /// A reference to a Type by name.
 class TypeReference extends TypeBase {
   static final TypeBase Undefined = TypeReference('undefined');
-  static final TypeBase Null_ = TypeReference('null');
-  static final TypeBase Any = TypeReference('any');
+  static final TypeBase Null_ = TypeReference('Null');
+
+  /// Any object (but not null).
+  static final TypeBase LspObject = TypeReference('Object');
+
+  /// Any object (or null/undefined).
+  static final TypeBase LspAny = NullableType(TypeReference('Object'));
   final String name;
   final List<TypeBase> typeArgs;
 
@@ -238,8 +267,8 @@
 
   @override
   String get dartType {
-    // Always resolve type aliases when asked for our Dart type.
-    final resolvedType = resolveTypeAlias(this);
+    // Resolve any renames when asked for our type.
+    final resolvedType = resolveTypeAlias(this, onlyRenames: true);
     if (resolvedType != this) {
       return resolvedType.dartType;
     }
@@ -249,14 +278,12 @@
       'string': 'String',
       'number': 'num',
       'integer': 'int',
+      'null': 'Null',
       // Map decimal to num because clients may sent "1.0" or "1" and we want
       // to consider both valid.
       'decimal': 'num',
       'uinteger': 'int',
-      'any': 'Object?',
-      'LSPAny': 'Object?',
       'object': 'Object?',
-      'LSPObject': 'Object?',
       // Simplify MarkedString from
       //     string | { language: string; value: string }
       // to just String
@@ -269,8 +296,8 @@
 
   @override
   String get typeArgsString {
-    // Always resolve type aliases when asked for our Dart type.
-    final resolvedType = resolveTypeAlias(this);
+    // Resolve any renames when asked for our type.
+    final resolvedType = resolveTypeAlias(this, onlyRenames: true);
     if (resolvedType != this) {
       return resolvedType.typeArgsString;
     }
@@ -294,8 +321,6 @@
     types.sortBy((type) => type.dartTypeWithTypeArgs.toLowerCase());
   }
 
-  UnionType.nullable(TypeBase type) : this([type, TypeReference.Null_]);
-
   @override
   String get dartType {
     if (types.length > 4) {
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart b/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
index ff348a3..77a5af9 100644
--- a/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.dart
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model_cleaner.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 'package:collection/collection.dart';
+
 import 'meta_model.dart';
 
 /// Helper methods to clean the meta model to produce better Dart classes.
@@ -162,7 +164,8 @@
     return TypeAlias(
       name: typeAlias.name,
       comment: _cleanComment(typeAlias.comment),
-      baseType: typeAlias.baseType,
+      baseType: _cleanType(typeAlias.baseType),
+      isRename: typeAlias.isRename,
     );
   }
 
@@ -184,8 +187,8 @@
     // types, we should just treat the whole thing as Object? as we get no value
     // typing Either4<bool, String, num, Object?> but it becomes much more
     // difficult to use.
-    if (uniqueTypes.any(isAnyType)) {
-      return uniqueTypes.firstWhere(isAnyType);
+    if (uniqueTypes.any(isNullableAnyType)) {
+      return uniqueTypes.firstWhere(isNullableAnyType);
     }
 
     // Finally, sort the types by name so that we always generate the same type
@@ -196,11 +199,19 @@
     // Recursively clean the inner types.
     uniqueTypes = uniqueTypes.map(_cleanType).toList();
 
-    return uniqueTypes.length == 1
-        ? uniqueTypes.single
-        : uniqueTypes.every(isLiteralType)
-            ? LiteralUnionType(uniqueTypes.cast<LiteralType>())
-            : UnionType(uniqueTypes);
+    if (uniqueTypes.length == 1) {
+      return uniqueTypes.single;
+    } else if (uniqueTypes.every(isLiteralType)) {
+      return LiteralUnionType(uniqueTypes.cast<LiteralType>());
+    } else if (uniqueTypes.any(isNullType)) {
+      final remainingTypes = uniqueTypes.whereNot(isNullType).toList();
+      final nonNullType = remainingTypes.length == 1
+          ? remainingTypes.single
+          : UnionType(remainingTypes);
+      return NullableType(nonNullType);
+    } else {
+      return UnionType(uniqueTypes);
+    }
   }
 
   /// Improves types in code generated from the LSP model, including:
@@ -235,7 +246,7 @@
             ? ArrayType(TypeReference(
                 improvedTypeName.substring(0, improvedTypeName.length - 2)))
             : improvedTypeName.endsWith('?')
-                ? UnionType.nullable(TypeReference(
+                ? NullableType(TypeReference(
                     improvedTypeName.substring(0, improvedTypeName.length - 1)))
                 : TypeReference(improvedTypeName)
         : null;
@@ -353,29 +364,42 @@
           'SignatureInformationParameterInformation',
       'TextDocumentFilter2': 'TextDocumentFilterWithScheme',
       'PrepareRenameResult1': 'PlaceholderAndRange',
+      'URI': 'LspUri',
     };
 
     for (final type in types) {
-      if (type is Interface) {
-        final newName = renames[type.name];
-        if (newName != null) {
-          // Replace with renamed interface.
-          yield Interface(
-            name: newName,
-            comment: type.comment,
-            baseTypes: type.baseTypes,
-            members: type.members,
-          );
-          // Plus a TypeAlias for the old name.
-          yield TypeAlias(
-            name: type.name,
-            comment: type.comment,
-            baseType: TypeReference(newName),
-          );
-          continue;
-        }
+      final newName = renames[type.name];
+      if (newName == null) {
+        yield type;
+        continue;
       }
-      yield type;
+
+      // Add a TypeAlias for the old name.
+      yield TypeAlias(
+        name: type.name,
+        comment: type.comment,
+        baseType: TypeReference(newName),
+        isRename: true,
+      );
+
+      // Replace the type with an equivalent with the same name.
+      if (type is Interface) {
+        yield Interface(
+          name: newName,
+          comment: type.comment,
+          baseTypes: type.baseTypes,
+          members: type.members,
+        );
+      } else if (type is TypeAlias) {
+        yield TypeAlias(
+          name: newName,
+          comment: type.comment,
+          baseType: type.baseType,
+          isRename: type.isRename,
+        );
+      } else {
+        throw 'Renaming ${type.runtimeType} is not implemented';
+      }
     }
   }
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart b/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
index 231da08..3be39a9 100644
--- a/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
+++ b/pkg/analysis_server/tool/lsp_spec/meta_model_reader.dart
@@ -48,6 +48,7 @@
       ...?enums?.map((e) => _readEnum(e)),
       ...?typeAliases?.map(_readTypeAlias),
     ].forEach(_addType);
+
     final methodsEnum = _createMethodNamesEnum(methodNames);
     if (methodsEnum != null) {
       _addType(methodsEnum);
@@ -174,6 +175,7 @@
         final generatedName = _generateAvailableTypeName(parentName, fieldName);
         return _extractType(generatedName, null, item);
       }).toList();
+
       return UnionType(types);
     } else if (model['kind'] == 'tuple') {
       // We currently just map tuples to an array of any of the types. The
@@ -278,6 +280,7 @@
       name: name,
       comment: model['documentation'] as String?,
       baseType: _extractType(name, null, model['type']),
+      isRename: false,
     );
   }
 }
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index f90aba4..807b974e 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -1568,6 +1568,7 @@
     var errorSource = {
       Compiler.dart2analyzer: ErrorSource.analyzer,
       Compiler.dart2js: ErrorSource.web,
+      Compiler.dart2wasm: ErrorSource.web,
       Compiler.dartdevc: ErrorSource.web,
       Compiler.fasta: ErrorSource.cfe
     }[testCase.configuration.compiler]!;
diff --git a/runtime/tests/vm/dart/regress_b_230945329_test.dart b/runtime/tests/vm/dart/regress_b_230945329_test.dart
new file mode 100644
index 0000000..46c9b84
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_b_230945329_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2022, 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.
+
+// Regression test for b/230945329.
+//
+// Check that AssertAssignables for the same uninstantiated type, where the
+// instantiated types at runtime may differ, are not optimized away.
+//
+// VMOptions=--no-use-field-guards --no-use-osr --deterministic --optimization-counter-threshold=5
+
+void main() {
+  final bar = Box<dynamic>('a'); // T=dynamic
+  final barInt = Box<int>(1); // T=int
+
+  for (int i = 0; i < 5; ++i) {
+    bar.bar(bar);
+  }
+  try {
+    barInt.bar(bar);
+    throw 'that should have failed!';
+  } on TypeError catch (e, s) {}
+}
+
+class Box<T> {
+  final T v;
+  Box(this.v);
+
+  void bar(Box box) {
+    // The uninstantiated compile type of box.v is T, same as the uninstantiated
+    // compile type it's being checked against. It's only the instantiated
+    // versions at runtime that could differ: the first instance type argument
+    // of box (box.v) vs. the first instance type argument of this (T).
+    baz(box.v/*=T*/ as T/*=T*/);
+  }
+}
+
+@pragma('vm:never-inline')
+baz(e) {}
diff --git a/runtime/tests/vm/dart_2/regress_b_230945329_test.dart b/runtime/tests/vm/dart_2/regress_b_230945329_test.dart
new file mode 100644
index 0000000..86c422d
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_b_230945329_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, 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.
+
+// Regression test for b/230945329.
+//
+// Check that AssertAssignables for the same uninstantiated type, where the
+// instantiated types at runtime may differ, are not optimized away.
+//
+// VMOptions=--no-use-field-guards --no-use-osr --deterministic --optimization-counter-threshold=5
+//
+// @dart=2.9
+
+void main() {
+  final bar = Box<dynamic>('a'); // T=dynamic
+  final barInt = Box<int>(1); // T=int
+
+  for (int i = 0; i < 5; ++i) {
+    bar.bar(bar);
+  }
+  try {
+    barInt.bar(bar);
+    throw 'that should have failed!';
+  } on TypeError catch (e, s) {}
+}
+
+class Box<T> {
+  final T v;
+  Box(this.v);
+
+  void bar(Box box) {
+    // The uninstantiated compile type of box.v is T, same as the uninstantiated
+    // compile type it's being checked against. It's only the instantiated
+    // versions at runtime that could differ: the first instance type argument
+    // of box (box.v) vs. the first instance type argument of this (T).
+    baz(box.v as T);
+  }
+}
+
+@pragma('vm:never-inline')
+baz(e) {}
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index b163fbe..02ef88e 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -853,7 +853,20 @@
   if (other.IsTopTypeForSubtyping()) {
     return true;
   }
-  if (IsNone()) {
+  // If we allow comparisons against an uninstantiated type, then we can
+  // end up incorrectly optimizing away AssertAssignables where the incoming
+  // value and outgoing value have CompileTypes that would return true to the
+  // subtype check below, but at runtime are instantiated with different type
+  // argument vectors such that the relation does not hold for the runtime
+  // instantiated values.
+  //
+  // We might consider using an approximation of the uninstantiated type,
+  // like the instantiation to bounds, and compare to that. However, in
+  // vm/dart_2/regress_b_230945329_test.dart we have a case where the compared
+  // uninstantiated type is the same as the one in the CompileType. Thus, no
+  // approach will be able to distinguish the two types, and so we fail the
+  // comparison in all cases.
+  if (IsNone() || !other.IsInstantiated()) {
     return false;
   }
   if (is_nullable() && !Instance::NullIsAssignableTo(other)) {
diff --git a/tools/VERSION b/tools/VERSION
index 94ce803..0bb2ec4 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 196
+PRERELEASE 197
 PRERELEASE_PATCH 0
\ No newline at end of file